Haskell中的(1 2)是什么类型的?

时间:2015-10-13 12:06:34

标签: haskell hugs

今天我一直在玩拥抱,并陷入了一个非常简单的问题:

λ 1 1
:: (Num a, Num (a -> t)) => t

那种类型是什么?我很难读到这个。

如果它有类型,为什么?我猜测表达式1 1是不正确的,因此类型检查失败,Haskell编译器支持它。

2 个答案:

答案 0 :(得分:12)

不,它没有形成错误。这种类型很奇怪,可能没有任何有意义的值,但它仍然是允许的。

请记住文字已超载。 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

其中fg是返回数字的函数。

使用上述实例声明1 2将等于1。 基本上,用作上述实例的函数的文字等于const <that-literal>

答案 1 :(得分:5)

在Haskell中,1没有固定类型。它是&#34;任何数字类型&#34;。更准确地说,是实现Num类的任何类型。

特别是,函数类型在技术上对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