seq功能文档说明如下:
关于评估顺序的注释:表达式
seq a b不保证a将在之前进行评估b.给出的唯一保证seq是,既a和b会前进行评估seq返回一个值.特别是,这意味着b可以在之前进行评估a.如果需要保证特定的评估顺序,则必须使用pseq"并行"软件包中的功能.
所以我有一个sum带累加器的懒函数:
sum :: Num a => [a] -> a
sum = go 0
where
go acc [] = acc
go acc (x:xs) = go (x + acc) xs
Run Code Online (Sandbox Code Playgroud)
显然,这在大名单上非常缓慢.现在我用seq以下方法重写这个函数:
sum :: Num a => [a] -> a
sum = go 0
where
go acc [] = acc
go acc (x:xs) = …Run Code Online (Sandbox Code Playgroud) 我有以下程序:
data Peano = Zero | Succ Peano deriving (Show)
add Zero b = b
add (Succ a) b = add a (Succ b)
mul Zero b = Zero
mul (Succ a) b = add b (mul a b)
four x = let two = Succ (Succ Zero) in mul two two
Run Code Online (Sandbox Code Playgroud)
我想从GHC得到这样的东西:
add =
\ ds b ->
case ds of
Zero ->
b
Succ a ->
add
a
(Succ b)
mul =
\ ds b ->
case ds …Run Code Online (Sandbox Code Playgroud) 考虑一下最近一个问题中的一个简单函数:
myButLast :: [a] -> a
myButLast [x, y] = x
myButLast (x : xs) = myButLast xs
myButLast _ = error "List too short"
Run Code Online (Sandbox Code Playgroud)
我们可以要求GHC给我们提供的简化输出ghc -ddump-simpl。(可能有一些额外的标志一样-dsuppress-module-prefixes -dsuppress-uniques)。据我了解,这是编译的最后阶段,结果仍然有任何外表到原来的高级代码。所以这就是它的意思:
-- RHS size: {terms: 21, types: 22, coercions: 0, joins: 0/0}
myButLast :: forall a. [a] -> a
[GblId,
Arity=1,
Str=<S,1*U>,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 100 0}]
myButLast
= \ (@ a) (ds :: [a]) ->
case ds …Run Code Online (Sandbox Code Playgroud)