簡體   English   中英

為什么Haskell沒有概括某些函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM