我在文件中有以下内容:
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
更受限制的类型存在差异?
答案 0 :(得分:10)
这是单态限制。
要点是,当你有一个受约束的类型变量时,如果Haskell绑定到一个标识符,它将不会推广
f = term
但是,如果它是一个功能绑定,例如
f a ... = term
然后它被推广。我已经回答了这个问题,我在blog post
中写了一个更完整的例子至于为什么我们有单态限制,
-- 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
在两种情况下comp
得到的comp
是相同的,它不能分享结果{{1}}