2017-03-17 24 views
0

今天我们提到了类型变量。但我不明白它的意思。我只能在wiki上找到一个解释,type variable什么是haskell中的类型变量/ Java

我理解数学中的解释,但仍然不知道编程。任何人都可以给出解释吗?

+0

我认为你只是要找到适合类型变量ocaml的例子,他们不是在数学意义上的实现Java的。当我听到haskell时,我认为[monad](https://wiki.haskell.org/Monad)(但我并不真正了解haskell)。 –

+0

*我们*在哪里提及类型变量?无论如何,你问的是一个Java泛型类型变量,也被称为“[类型参数](https://docs.oracle.com/javase/tutorial/java/generics/types.html)”(⇐链接到“ Java™教程“)? – Andreas

+1

@Andreas那么,刚才对你来说...... –

回答

0

使用Type变量,您可以为非指定类型的事物(Numbers,Text,...)定义数据类型/容器。为了提供一个简单的例子,想象一下,你需要一个Box,在那里你可以放入任何你想要的东西。

这里是在Java中的例子(T是类型变量):

public class Box<T> { 
    private T thing; 

    public void putThing(T thing) { 
     this.thing = thing; 
    } 
} 

这里是在Haskell一个例子(一个是类型变量):

data Box a = PutThing a 

另一个好例子将是一个通用的元组数据类型。


例usecases

注意,在两种情况下,类型变量现在指定的类型。

的Java:

Box<String> box = new Box<String>(); 
box.putThing("42");  

哈斯克尔(在ghci中):

:t (PutThing (42::Int)) 
(PutThing (42::Int)) :: Box Int 
1

类型变量是一种通过编写单个函数/方法来处理多种不同类型值的方法。这是在Haskell一个例子:

id :: forall a. a -> a 
id x = x 

在类型签名的a是一个类型变量,而作为forall意味着,这个函数是“所有”不同的类型。例如,您可以使用id,就好像它的类型为Int -> Int或者好像它的类型为Char -> Char一样。

id (5 :: Int) = 5 :: Int 
id 'a' = 'a' 

如果id被赋予了具体的类型,如id :: Int -> Int(没有在它的类型变量的意思),然后id 'a'将是一个类型的错误,因为'a'的类型(Char)不匹配Int

通常,我们省略了forallid :: a -> a),因为它可以很容易地从使用类型变量中推断出来,但它有助于理解实际发生的情况。

我不像Haskell那么了解Java,但泛型似乎是一种使用类型变量的方式,所以ArrayList<A>意味着一个数组列表,它适用于任何非原始类型A

+0

Java通用类型不适用于原始类型,它们是编译时类型的安全系统(在编译时它们通常被清除*)。所以他们在任何意义上都不是“纯粹的”...... –

+0

@ElliottFrisch你是什么意思,他们不适用于原始类型?我不能使用ArrayList '吗? [* Haskell中的所有*类型信息在运行时被删除](http://stackoverflow.com/questions/12468722/does-haskell-erase-types),所以它们在这方面是相似的。这对这种“纯粹”的任何事情有何影响?如果你的意思是纯粹的“没有副作用”,我不明白这是如何适用于此。 – Lazersmoke

+0

不可以。您不能使用'ArrayList '或*'ArrayList '。你必须使用包装类型。 –

2

好吧,这很容易。基本的观察是,我们不仅具有像Int和Bool和Char这样的基本类型,而且还包含由其他类型组成的类型。

最简单的例子是列表。在类型安全的语言中,列表中的所有元素必须具有相同的类型。这就是为什么我们写:

Haskell Java    Explanation 
[Int]  List<Integer>  list of integers 
[Char] List<Character> list of characters 

等等。这很好,但不够好。事实证明,除了元素类型,列表中的某些函数是完全相同的,并且元素类型在函数内部是不相关的。下面是一个例子:

lengthIntList :: [Int] -> Int -- compute length of a list of int 
lengthIntList [] = 0 
lengthIntList (x:xs) = 1 + length xs 

lengthCharList :: [Char] -> Int -- compute length of a list of char 
lengthCharList [] = 0 
lengthCharList (x:xs) = 1 + length xs 

因此,下一个步骤是从元素类型抽象和说:

length :: [a] -> Int  -- length of a list, for all elemen types 
length [] = 0 
length (x:xs) = 1 + length xs 

这里,a是一种类型的变量表示:对于所有类型的,这功能length获取该类型的列表并返回Int

2

从维基百科该实施例可以用Java编写这样

public static <T> T identity(T a) { 
    return a; 
} 

其中a类型被绑定到类型参数T。因此,当您拨打Integer致电身份识别功能时,您会收到一个Integer,当您拨打String时,您会收到String

一个非常常见的用法的例子是像字符串的列表相同类型的值的集合:

List<String> as = new ArrayList<String>(); 

List接口类型参数绑定到String因此该列表中的所有元素必须类型为String

更新代码片段,谢谢Elliott。

+0

你的例子里有什么't'?你是不是指'回来一个;'? –

相关问题