Elm严格和延迟的评估
示例
在elm中,当应用最后一个参数时,将计算函数的值。在以下示例中,log当使用3个参数调用f或使用最后一个参数应用f的咖喱形式时,将打印诊断自。
import String import Debug exposing (log) f a b c =String.join"," (log "Diagnostic" [a,b,c]) -- <function> : String -> String -> String -> String f2 = f "a1" "b2" -- <function> : String -> String f "A" "B" "C" -- Diagnostic: ["A","B","C"] "A,B,C" : String f2 "c3" -- Diagnostic: ["a1","b2","c3"] "a1,b2,c3" : String
有时您会希望阻止立即应用某个功能。elm中的典型用法是Lazy.lazy为控制何时应用功能提供抽象。
lazy : (() -> a) -> Lazy a
惰性计算采用一个()或一个Unit类型参数的函数。单位类型通常是占位符参数的类型。在参数列表中,对应的参数指定为_,指示未使用该值。elm中的单位值由特殊符号指定,该符号()在概念上可以表示空元组或孔。它类似于C,Javascript和其他使用圆括号进行函数调用的语言中的空参数列表,但这是一个普通值。
在我们的示例中,f可以防止使用lambda立即对其进行评估:
doit f = f () -- <function> : (() -> a) -> a whatToDo = \_ -> f "a" "b" "c" -- <function> : a -> String -- f is not evaluated yet doit whatToDo -- Diagnostic: ["a","b","c"] "a,b,c" : String
任何时候部分应用功能都会延迟功能评估。
defer a f = \_ -> f a -- <function> : a -> (a -> b) -> c -> b delayF = f "a" "b" |> defer "c" -- <function> : a -> String doit delayF -- Diagnostic: ["a","b","c"] "a,b,c" : String
Elm具有always无法用于延迟评估的功能。因为elm会评估所有函数参数,而不管是否以及何时使用函数应用程序的结果,所以将函数应用程序包装在中always不会引起延迟,因为f它完全用作的参数always。
alwaysF = always (f "a" "b" "c") -- <function> : a -> String -- Diagnostic: ["a","b","c"] -- Evaluation wasn't delayed.