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

Jen*_*ens 6 haskell hugs

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

? 1 1
:: (Num a, Num (a -> t)) => t
Run Code Online (Sandbox Code Playgroud)

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

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

Bak*_*riu 12

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

请记住,文字是重载的.1不是一个整数.它是任何类型的东西Num.功能排除在此之外.没有规则说a -> t 不能是"数字"(即一个实例Num).

例如,你可以有一个instance声明如下:

instance Num a => Num (a -> b) where
    fromInteger x = undefined
    [...]
Run Code Online (Sandbox Code Playgroud)

现在1 1简直是平等的undefined.不是很有用但仍然有效.

可以拥有有用的Num函数定义.例如,来自维基

instance Num b => Num (a -> b) where
     negate      = fmap negate
      (+)         = liftA2 (+)
      (*)         = liftA2 (*)
      fromInteger = pure . fromInteger
      abs         = fmap abs
      signum      = fmap signum
Run Code Online (Sandbox Code Playgroud)

有了这个,你可以写下这样的东西:

f + g
Run Code Online (Sandbox Code Playgroud)

where fgare函数返回数字.

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


Mat*_*hid 5

在Haskell中,1没有固定类型.它是"任何数字类型".更准确地说,是实现Num该类的任何类型.

特别是,对于函数类型来说,它在技术上是有效的Num.没有人会这样做,但从技术上讲,这是可能的.

所以编译器假设第一个 1是某种数字函数类型,然后第二个 1是任何其他数字类型(可能是相同的类型,也许是不同的类型).如果我们将表达式更改为,比方说3 6,那么编译器就是假定的

3 :: Num (x -> y) => x -> y
6 :: Num x => x
3 6 :: (Num (x -> y), Num x) => y
Run Code Online (Sandbox Code Playgroud)