中執行類型推斷我通過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