我试图了解是否会懒惰地评估以下函数。
我的理解是“head”将从列表中取出第一项。 OptimalTests会评估[Test]中的第一个项目,还是在随后调用head之前创建[Test]中的所有测试?
optimalTests :: State -> [Test]
--implementation here
getAnyTest :: State -> Test
getAnyTest s = head(optimalTests s)
我建议在:print
中使用:sprint
和ghci
命令搞乱,看看在行动中的懒惰评估。例如:
Prelude> let names = ["Joe", "Jen", "Anne"]
Prelude> let hellos = map ((++) "Hello ") names
Prelude> head hellos
"Hello Joe"
Prelude> :sprint hellos
hellos = "Hello Joe" : _
Prelude> length hellos
3
Prelude> :sprint hellos
hellos = ["Hello Joe",_,_]
Prelude> last hellos
"Hello Anne"
Prelude> :sprint hellos
hellos = ["Hello Joe",_,"Hello Anne"]
这样,您可以看到在调用不同函数时如何逐步评估列表。 _
代表了一个无价值的thunk。
您可以将代码加载到ghci
并以类似的方式进行实验。只需确保将内容分配给变量,否则它们将由REPL进行评估。
你是对的,它只会创造第一个值,没有别的......
您可以通过返回在第二个元素上崩溃的数组来测试它。
optimalTests _ = [aValidValue, error "crash!"]
如果程序没有崩溃(它不会),这意味着它从未尝试过评估第二个项目。