Haskell折叠在无限列表上,不应用惰性评估

问题描述 投票:0回答:1

根据我的理解,因为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不能从这里的懒惰评估中受益?

haskell lazy-evaluation fold foldleft
1个回答
0
投票

因为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
© www.soinside.com 2019 - 2024. All rights reserved.