在应用程序的上下文中理解Haskell类型系统

z1n*_*Y5A 4 haskell type-systems applicative

我正在玩,Control.Applicative我意识到我不了解Haskell类型系统的一切.

这是我在Ghci的实验:

? :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b

? :t (<*>) (pure 2)
(<*>) (pure 2) :: (Num (a -> b), Applicative f) => f a -> f b
Run Code Online (Sandbox Code Playgroud)

第一个参数的类型<*>f (a -> b).

  • 为什么这个表达正确?
  • 它是如何统一的,(pure 2)因为常量2不是类型a -> b
  • 什么Num (a -> b)意思?具有a -> b类型的函数如何成为Num?的实例?

Mat*_*hid 7

<*>应该是第一个参数f (a -> b).所以(<*>) (pure x),这是一种很好的类型,只要它x是某种功能.

类型2Num a => a.换句话说,2可以是任何可能的类型,只要它是一个实例Num.

所以在你的表达式中(<*>) (pure 2),只要类型2是函数类型,并且该函数类型具有Num实例,这是良好类型的.

当然,几乎没有理由要求函数拥有Num实例.但是编译器不知道这一点.所有它的说法是,如果有这样的实例,那么表达式将变得很好.

(这类似于在编译器想要一些类型为实例的错误,你有时会看到IntegralFractional同时为了人类,这是荒谬的组合,为机器,他们只是两个普通班......)

  • 它不是默认的,但这样做是可以接受的(阅读:守法).上面给出的代码augustss的片段是有效的(如果是部分的)`实例Num b => Num(a - > b)`.你要求的相关部分看起来像`fromInteger a = const(fromInteger a)`.关于`Applicative`s,你可以看到这只不过是将`Num`方法提升到`Reader``Applied`,`类型Reader ab =(a - > b)`.例如,`fromInteger a = pure(fromInteger a)`和`(+)= liftA2(+)`. (2认同)