Haskell 中 (1 2) 的类型是什么?
What is the type of (1 2) in Haskell?
今天我在玩拥抱,被一个很简单的问题卡住了:
λ 1 1
:: (Num a, Num (a -> t)) => t
那个类型是什么?我无法阅读此内容。
如果它有类型,为什么?我猜测表达式 1 1
格式错误,因此类型检查失败,Haskell 编译器支持。
在Haskell中,1
没有固定的类型。是"any numeric type"。更准确地说,任何实现 Num
class.
的类型
特别是,函数类型作为Num
的实例在技术上是有效的。没有人会那样做,但从技术上讲这是可能的。
所以编译器假设 first 1
是某种数字函数类型,然后是 second 1
是任何其他数字类型(可能是同一类型,也可能是不同类型)。如果我们将表达式更改为 3 6
,那么编译器会假设
3 :: Num (x -> y) => x -> y
6 :: Num x => x
3 6 :: (Num (x -> y), Num x) => y
不,它不是格式错误的。类型很奇怪,可能没有任何有意义的值,但它仍然被允许。
请记住文字是超载的。 1
是 不是 整数。可以是 Num
类型的任何内容。函数不被排除在外。没有规则说 a -> t
不能 是“数字”(即 Num
的实例)。
例如,您可以有一个 instance
声明,例如:
instance Num a => Num (a -> b) where
fromInteger x = undefined
[...]
现在 1 1
将等于 undefined
。不是很有用,但仍然有效。
您可以 对函数有有用的 Num
定义。例如,来自 wiki
instance Num b => Num (a -> b) where
negate = fmap negate
(+) = liftA2 (+)
(*) = liftA2 (*)
fromInteger = pure . fromInteger
abs = fmap abs
signum = fmap signum
有了这个你可以写这样的东西:
f + g
其中 f
和 g
是返回数字的函数。
使用上面的实例声明 1 2
将等于 1
。
基本上用作上述实例的函数的文字等于 const <that-literal>
.
今天我在玩拥抱,被一个很简单的问题卡住了:
λ 1 1
:: (Num a, Num (a -> t)) => t
那个类型是什么?我无法阅读此内容。
如果它有类型,为什么?我猜测表达式 1 1
格式错误,因此类型检查失败,Haskell 编译器支持。
在Haskell中,1
没有固定的类型。是"any numeric type"。更准确地说,任何实现 Num
class.
特别是,函数类型作为Num
的实例在技术上是有效的。没有人会那样做,但从技术上讲这是可能的。
所以编译器假设 first 1
是某种数字函数类型,然后是 second 1
是任何其他数字类型(可能是同一类型,也可能是不同类型)。如果我们将表达式更改为 3 6
,那么编译器会假设
3 :: Num (x -> y) => x -> y
6 :: Num x => x
3 6 :: (Num (x -> y), Num x) => y
不,它不是格式错误的。类型很奇怪,可能没有任何有意义的值,但它仍然被允许。
请记住文字是超载的。 1
是 不是 整数。可以是 Num
类型的任何内容。函数不被排除在外。没有规则说 a -> t
不能 是“数字”(即 Num
的实例)。
例如,您可以有一个 instance
声明,例如:
instance Num a => Num (a -> b) where
fromInteger x = undefined
[...]
现在 1 1
将等于 undefined
。不是很有用,但仍然有效。
您可以 对函数有有用的 Num
定义。例如,来自 wiki
instance Num b => Num (a -> b) where
negate = fmap negate
(+) = liftA2 (+)
(*) = liftA2 (*)
fromInteger = pure . fromInteger
abs = fmap abs
signum = fmap signum
有了这个你可以写这样的东西:
f + g
其中 f
和 g
是返回数字的函数。
使用上面的实例声明 1 2
将等于 1
。
基本上用作上述实例的函数的文字等于 const <that-literal>
.