我在文件中有以下内容:
import Control.Monad
ema a = scanl1 $ \m n -> (1-a)*m + a*n
macd = ema 9 . uncurry (zipWith (-)) . liftM2 (,) (ema 26) (ema 12)
Run Code Online (Sandbox Code Playgroud)
在编译时,我得到以下内容:
:t macd
macd :: [Integer] -> [Integer]
Run Code Online (Sandbox Code Playgroud)
然而,
:t ema 9 . uncurry (zipWith (-)) . liftM2 (,) (ema 26) (ema 12)
ema 9 . uncurry (zipWith (-)) . liftM2 (,) (ema 26) (ema 12)
:: Num a => [a] -> [a]
Run Code Online (Sandbox Code Playgroud)
那么,为什么在更受限制的类型中存在差异macd
呢?
Dan*_*zer 10
这是单态限制.
要点是,当你有一个受约束的类型变量时,如果Haskell绑定到一个标识符,它将不会推广
f = term
Run Code Online (Sandbox Code Playgroud)
但是,如果它是一个功能绑定,例如
f a ... = term
Run Code Online (Sandbox Code Playgroud)
然后它被推广.我已经回答了这个问题,我在博文中写了一个更完整的例子
至于为什么我们有单态限制,
-- let's say comp has the type [Num a => a]
foo = (comp, comp)
where comp = super_expensive_computation
Run Code Online (Sandbox Code Playgroud)
comp
计算多少次?如果我们自动推断一般类型,它可以计算两次.但是如果你写这样的东西想要有类型Num a => (a, a)
或类似的东西,这可能会让你感到惊讶.
额外的计算是因为在核心土地之类的东西
foo :: Num a => a
Run Code Online (Sandbox Code Playgroud)
变成更像的东西
foo :: NumDict -> a -- NumDict has the appropriate functions for + - etc
-- for our a
Run Code Online (Sandbox Code Playgroud)
一个功能.由于foo
一般类型是(Num a, Num b) => (a, b)
除非GHC可以证明在两种情况下得到的NumDict
s comp
是相同的,它不能分享结果comp