当我有以下代码时:
func n = m ++ [1] ++ m ++ [0] ++ m
where m = func2 n
Run Code Online (Sandbox Code Playgroud)
func2函数调用了多少次?只有一次,在where子句中?或者每次使用m时它是否只是再次计算?
Car*_*ten 19
也许它根本没有评估(懒惰的喜悦) - 但如果是,它应该只被评估一次 - 如果你愿意,你可以尝试自己trace
:
import Debug.Trace(trace)
func n = m ++ [1] ++ m ++ [0] ++ m
where m = func2 n
func2 n = trace "called..." [n]
Run Code Online (Sandbox Code Playgroud)
这是GHCi中的一个例子:
?> func 3
called...
[3,1,3,0,3]
Run Code Online (Sandbox Code Playgroud)
在这里你可以看到它可能不被调用(直到你最终需要评估它):
?> let v = func 4
?> v
called...
[4,1,4,0,4]
Run Code Online (Sandbox Code Playgroud)
请参阅:首先它没有被调用 - 只有当你最终评估v
(打印它)时才能接到电话.
只要您没有禁用单态限制,Carsten的答案(该值最多只能计算一次)是正确的.如果你有,那么m
可能有一个涉及类型类的多态推断类型,然后m
它不是一个普通的值,而是一个接受类型类字典并产生一个值的函数.考虑这个例子.
{-# LANGUAGE NoMonomorphismRestriction #-}
import Debug.Trace(trace)
func n = m ++ [1] ++ m ++ [0] ++ m
where m = func2 n -- m :: Monad t => t a (where n :: a)
func2 n = trace "called..." (return n) -- func2 :: Monad t => a -> t a
Run Code Online (Sandbox Code Playgroud)
然后func 3
在ghci打印中进行评估
called...
[3,1called...
,3,0called...
,3]
Run Code Online (Sandbox Code Playgroud)