【发布时间】:2016-01-24 10:53:44
【问题描述】:
如果我强制 Haskell 推断数字的类型,我会得到 Num a => a。例如:
Prelude> :t 1
1 :: Num a => a
但是a => a 是什么意思?
【问题讨论】:
-
这可能会回答你的问题,stackoverflow.com/a/3742700/5781248
标签: haskell
如果我强制 Haskell 推断数字的类型,我会得到 Num a => a。例如:
Prelude> :t 1
1 :: Num a => a
但是a => a 是什么意思?
【问题讨论】:
标签: haskell
1 :: Num a => a 表示1 具有某种类型a,其中a 是Num 类型类的一个实例。注意Num不是一个类型,而是一个类型类,它描述了各种类型的共同属性。例如,Num 类型类描述了数字类型,因此支持基本算术。本机整数类型Int是Num的一个实例,任意大小的Integer、浮点类型Double,甚至有理数类型Rational也是如此。
【讨论】:
1 的每个实例在运行时只有一种类型。尝试做(,) <$> (+ (1 :: Int)) <*> (+ (1 :: Float)) $ 1 之类的事情,你不会玩得开心。
1 在操作上是从 Num 字典到值的函数。来到 Haskell 的 OOP 程序员通常认为它是“一些”,这将允许像 p :: Num a => a; p = 1 :: Int 这样的东西。
a => a 没有任何意义。完整的短语是Num a => a。这意味着“a”是Num 类型类的一个实例。
您也可以将其读作(Num a) => a。它提供了一个上下文来说明 a 是数字。
但是,它不是a 的类型;它只是说 a 应该在 Num 类型 class 中。
类型类有点像面向对象编程中的接口,因为它们定义了某些行为,而没有详细定义 a。
请注意,-> 和 => 之间存在差异。第一个用于函数签名;第二个用于显示类型类。
【讨论】:
a 的类型是 Num。但是为什么我们需要说=> a呢?
Num a => a 是这样的:a 的类型为Num,它是一个a。这是一个模糊的。
Num a 告诉你一些关于a 的事情。 Num 是类型类,而不是类型。有点像面向对象编程中的接口,它定义了a 应该满足的一些条件,而无需详细定义a。
键入1 :: Num a => a 表示“1 的类型为a,对于类型类a 中的所有类型Num”。更简洁地说,它意味着“1 是任何数字类型”。
由于这种类型,您可以将1 传递给任何需要任何数字类型的函数,例如Int、Double 等。
稍微扩展您的示例,我们还有[1,2,3] :: Num a => [a]。这意味着“[1,2,3] 是 a 类型值的列表,适用于类型类 Num 中的所有类型 a”。换句话说,“[1,2,3] 是任何数字类型的值的列表”。
【讨论】:
表达式1::Num a => a 可以分为 3 个部分以供阅读/理解。
让我们一步一步构建:
1 :: 说 1 的类型为
c :: Char 说 c 的类型是 Char
=> 之前的所有内容都是“类约束”,所以在 :: 和 => 之间插入 Num a
即1 :: Num a => a 说 “1 具有 a 的类型,但不是任何类型,而是具有类约束,其中 a 是 Num 类的成员。
【讨论】: