关于Haskell惰性求值与列表推导式的函数执行逻辑问询
foo s1 s2 = null ([x | x <- s2, x == s1])
问题1:函数的执行结束条件
该函数的作用是判断值s1不存在于列表s2中,执行结束分两种情况:
- 遍历
s2的过程中找到第一个和s1相等的元素,此时列表推导生成包含该元素的非空列表,null判断结果为False,执行直接结束,不会继续遍历s2的剩余元素 - 完整遍历完
s2的所有元素,都没有找到和s1相等的元素,此时列表推导生成空列表,null判断结果为True,执行结束
问题2:遍历逻辑及优化
Haskell默认采用惰性求值策略,不会先遍历整个s2再执行null判断:null函数只需要判断列表的最外层构造器,不需要求值列表的剩余元素或者元素本身。当列表推导生成第一个符合条件的元素时,得到的列表结构为元素 : 未求值的剩余列表,null识别到这是非空列表就会直接返回结果,终止后续遍历。就算s2是无限列表,只要存在等于s1的元素,函数也能正常返回结果不会卡死。
如果希望代码可读性更高、更符合Haskell的惯用写法,可以直接用标准库的notElem函数替换,语义和原函数完全一致:
foo s1 s2 = s1 `notElem` s2
内容的提问来源于stack exchange,提问作者Acmades
相关产品推荐
相关产品推荐

