今天我们提到了类型变量。但我不明白它的意思。我只能在wiki上找到一个解释,type variable什么是haskell中的类型变量/ Java
我理解数学中的解释,但仍然不知道编程。任何人都可以给出解释吗?
今天我们提到了类型变量。但我不明白它的意思。我只能在wiki上找到一个解释,type variable什么是haskell中的类型变量/ Java
我理解数学中的解释,但仍然不知道编程。任何人都可以给出解释吗?
使用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
类型变量是一种通过编写单个函数/方法来处理多种不同类型值的方法。这是在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
。
通常,我们省略了forall
(id :: a -> a
),因为它可以很容易地从使用类型变量中推断出来,但它有助于理解实际发生的情况。
我不像Haskell那么了解Java,但泛型似乎是一种使用类型变量的方式,所以ArrayList<A>
意味着一个数组列表,它适用于任何非原始类型A
。
Java通用类型不适用于原始类型,它们是编译时类型的安全系统(在编译时它们通常被清除*)。所以他们在任何意义上都不是“纯粹的”...... –
@ElliottFrisch你是什么意思,他们不适用于原始类型?我不能使用ArrayList
不可以。您不能使用'ArrayList
好吧,这很容易。基本的观察是,我们不仅具有像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
。
从维基百科该实施例可以用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。
你的例子里有什么't'?你是不是指'回来一个;'? –
我认为你只是要找到适合类型变量ocaml的例子,他们不是在数学意义上的实现Java的。当我听到haskell时,我认为[monad](https://wiki.haskell.org/Monad)(但我并不真正了解haskell)。 –
*我们*在哪里提及类型变量?无论如何,你问的是一个Java泛型类型变量,也被称为“[类型参数](https://docs.oracle.com/javase/tutorial/java/generics/types.html)”(⇐链接到“ Java™教程“)? – Andreas
@Andreas那么,刚才对你来说...... –