[英]Why Doesn't Haskell Generalize Some Functions
我在文件中有以下內容:
import Control.Monad
ema a = scanl1 $ \m n -> (1-a)*m + a*n
macd = ema 9 . uncurry (zipWith (-)) . liftM2 (,) (ema 26) (ema 12)
在編譯時,我得到以下內容:
:t macd
macd :: [Integer] -> [Integer]
然而,
:t ema 9 . uncurry (zipWith (-)) . liftM2 (,) (ema 26) (ema 12)
ema 9 . uncurry (zipWith (-)) . liftM2 (,) (ema 26) (ema 12)
:: Num a => [a] -> [a]
那么,為什么macd
限制類型的區別呢?
這是單態限制。
要點是,當你有一個受約束的類型變量時,如果Haskell綁定到一個標識符,它將不會推廣
f = term
但是,如果它是一個功能綁定,例如
f a ... = term
然后它被推廣。 我已經回答了這個問題,我在博文中寫了一個更完整的例子
至於為什么我們有單態限制,
-- let's say comp has the type [Num a => a]
foo = (comp, comp)
where comp = super_expensive_computation
comp
計算多少次? 如果我們自動推斷一般類型,它可以計算兩次。 但是如果你寫了類似Num a => (a, a)
或類似的東西,這可能會讓你感到驚訝。
額外的計算是因為在核心土地之類的東西
foo :: Num a => a
變成更像的東西
foo :: NumDict -> a -- NumDict has the appropriate functions for + - etc
-- for our a
一個功能。 由於foo
的一般類型是(Num a, Num b) => (a, b)
除非GHC能夠證明NumDict
s表示comp
是在兩種情況下得到相同,它不能共享的結果comp
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.