ghc如何执行类型推断

pat*_*ues 3 haskell

我通过Paul Hudaks高度推荐的书籍Haskell School of Expression.在第13章中,我偶然发现了这个定义

type Time = Float

newtype Behavior a = Beh (Time -> a)
Run Code Online (Sandbox Code Playgroud)

作者声明的NEWTYPE的几个实例Behavior:Eq,Show,Num,FractionalFloating,但这些it's在被窃听我这些实例声明的一个只有一个函数中:

instance Num a => Num (Behavior a) where
  (+) = lift2 (+)                                   -- This one!
  fromInteger = lift0 . fromInteger

lift0 :: a -> Behavior a
lift0 x = Beh (\t -> x)

lift2 :: (a -> b -> c) -> (Behavior a -> Behavior b -> Behavior c)
lift2 g (Beh a) (Beh b)
   = Beh (\t -> g (a t) (b t))                      -- Or actually this one.

time :: Behavior Time
time = Beh (\t -> t)
Run Code Online (Sandbox Code Playgroud)

在此之后,作者描述了使用这些新的函数声明,我们现在可以编写time + 5并因此将(+)操作符提升到行为领域,或者以这种方式.这对我来说听起来很好,所以当我读书时,我点头微笑.突然,作者解释说:(time + 5)相当于Beh (\t -> t + 5),听起来完全被打击了.他实际上甚至提供了表达式的展开来证明它:

time + 5
==> { unfold overloadings for time, (+), and 5 }
(lift2 (+)) (Beh (\t -> t)) (Beh (\t -> 5))
==> { unfold lift2 }
(\ (Beh a) (Beh b) -> Beh (\t -> a t + b t)) (Beh (\t -> t)) (Beh (\t -> 5))
==> { unfold anonymous function }
Beh (\t -> (\t -> t) t + (\t -> 5) t )
==> { unfold two anonymous functions }
Beh (\t -> t + 5)
Run Code Online (Sandbox Code Playgroud)

更具体地说,这是我理解的问题.对我来说,正确的陈述是:time + (Beh 5)相当于Beh (\t -> t + 5).但是当我推断ghci中的类型时,它(当然)告诉我作者是正确的,并且我以某种正式方式愚蠢.有人可以向我解释一下.

tem*_*ept 5

(+)有类型Num a => a -> a -> a.这aBehavior Float.5您的代码中的文字将转换为Behavior Floatwith fromInteger,应该是这样的fromInteger n = Beh (\t -> fromInteger n).

Beh 5因为Beh包装了一个类型的函数而Float -> a不是一个数字,所以不会进行类型检查.