我有一个字符串列表,errors。我做了一些检查,如果有任何失败,我会在后面附加一条消息errors。像这样:
let errors = []
let errors' = errors ++ if (check1 fails) then ["check1 failed"] else []
let errors'' = errors' ++ if (check2 fails) then ["check2 failed"] else []
Run Code Online (Sandbox Code Playgroud)
当然,还有一种更惯用的方式来累积更改,errors而不必每次都生成新变量。我需要Data.IORef突显可变变量吗?似乎过分杀伤力。
如果仅删除撇号,则编译器将返回错误,因为它陷入了无限循环。
您可以将条件和消息分组在一起
checksTodo = [(check1 fails, "check1 failed"), (check2 fails, "check2 failed")]
errors = map snd (filter fst checksTodo)
Run Code Online (Sandbox Code Playgroud)
如果您愿意使用列表理解语法,则可以改用更易读的方式编写它:
errors = [ msg | (cond, msg) <- checksTodo, cond ]
Run Code Online (Sandbox Code Playgroud)
如果仅删除撇号,则编译器将返回错误,因为它陷入了无限循环。
发生这种情况是因为let默认情况下,Haskell中的绑定(不同于大多数语言)是递归的。这意味着如果你说
let errors = errors ++ if (check1 fails) then ["check1 failed"] else []
Run Code Online (Sandbox Code Playgroud)
编译器会将其视为递归定义。当您尝试errors在运行时求值时,您需要errors进行计算进入无限循环errors。