haskell / Java中的类型变量是什么

时间:2017-03-17 00:45:23

标签: java haskell

今天我们提到了类型变量。但我不明白这意味着什么。我只能在wiki上找到一个解释,type variable

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

4 个答案:

答案 0 :(得分:2)

嗯,这很容易。基本观察是我们不仅有基本类型,如Int和Bool和Char,还有其他类型的类型。

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

Important: make sure the Compute Engine API is enabled for your project on the

等等。这已经很好了,但还不够好。事实证明,除了元素类型之外,列表上的某些函数是完全相同的,并且元素类型在函数内部是无关紧要的。这是一个例子:

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

答案 1 :(得分:2)

维基百科的例子可以像这样用Java编写

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

其中a的类型绑定到类型参数T。因此,当您使用Integer调用身份函数时,您会返回Integer,当您使用String调用它时,您将获得String

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

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

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

更新了代码段,感谢Elliott。

答案 2 :(得分:1)

类型变量是一种通过编写适用于多种不同类型值的单个函数/方法来获得多态性的方法。这是Haskell中的一个例子:

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

类型签名中的a是一个类型变量,正如forall所暗示的那样,这个函数适用于所有&#34;不同种类。例如,您可以使用id,就像它具有类型Int -> Int一样,或者就像它具有类型Char -> Char一样。

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

如果id被赋予了具体类型(意味着没有类型变量),例如id :: Int -> Int,那么id 'a'将是类型错误,因为'a'&#39 ; s类型(Char)与Int不匹配。

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

我不知道Java和Haskell一样多,但是Generics似乎是一种使用类型变量的方法,因此ArrayList<A>表示适用于任何非基本类型{{1}的数组列表}}

答案 3 :(得分:1)

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

这是Java中的一个例子(T是类型变量):

public class Box<T> {
    private T thing;

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

以下是Haskell中的一个示例(a是类型变量):

data Box a = PutThing a

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

示例用例

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

爪哇:

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

Haskell(在ghci中):

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