根据我的理解,因为Haskell使用惰性评估,因此可以在有限的时间内评估例如无限列表上的操作。
作为测试,我定义了以下功能
X Boolean
Y Int
f(X,Y) = (Y == 3) OR X
因此,将以[1..]
作为初始值且上面定义的函数应用于整数False
的无限列表的左折,应该返回True
,因为当到达n=3
时评估f(n==3,False)
将返回True
,因此此True
将通过函数传播。
我用Haskell代码实现了此功能
myfunc :: Bool -> Int -> Bool
myfunc True _ = True
myfunc _ n
| (n == 3) = True
| otherwise = False
并在cli中进行了尝试
foldl myfunc False [1..]
该命令无响应,表明它正在执行无限计算。为什么Haskell不能从这里的懒惰评估中受益?
因为foldl
始终必须遍历其参数列表整个,然后再开始将其简化为最终结果; foldl'
遍历参数列表in全部,同时将其简化为最终结果。
您希望能够中止遍历,这是通过right折叠使用非严格归约功能完成的:
present y xs = foldr myfunc False xs
where
myfunc x r = y == x || r
因为myfunc
在其第二个参数中是非严格的,所以foldr myfunc
按照从左到右的顺序浏览列表xs
,
foldr myfunc False (x:xs) = myfunc x (foldr myfunc False xs)
= y == x || foldr myfunc False xs