中执行类型推断我通过Paul Hudaks强烈推荐的书Haskell School of Expression工作。 在13:Eq
,Show
,Num
,Fractional
和Floating
,但这些it's只有一个函数中:日章我碰到这个定义ghc如何在
type Time = Float
newtype Behavior a = Beh (Time -> a)
作者声明的NEWTYPE Behavior
的几个实例绊倒这些实例声明的一个是窃听我:
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)
笔者介绍,在此之后,随着这些新功能的声明,我们现在可以写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)
这更具体地是我有什么麻烦理解。对我来说正确的说法是:time + (Beh 5)
相当于Beh (\t -> t + 5)
。但是当我推断出ghci的类型时,它告诉我(当然)作者是正确的,而且我以某种正式的方式愚蠢。有人可以向我解释吗?
'贝5'将是错误的。它应该是'Beh(const 5)',因为'5'不是一个函数。 –
我认为你真正的问题是你错过了['fromInteger'](http://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#v:fromInteger)部分的' Num'类 - 这是将'5'包装到'Behaviour'中的地方;) – Carsten
表达式'time + 5'实际上等于'Beh(\ t→t +(5 t))'。查看'Num(行为a)'的'fromInteger'方法。关键的一点是整数文字有一个隐含的'fromInteger',所以当你写5时,它实际上是'fromInteger(5 :: Integer))'。 – augustss