惰性和功能组合(haskell,erlang)

惰性和功能组合(haskell,erlang),haskell,functional-programming,erlang,lazy-evaluation,Haskell,Functional Programming,Erlang,Lazy Evaluation,有人能解释一下或者提供一些关于函数组合如何与懒惰相关的资源吗 例如,如何过滤(/='W')。映射到Haskell中的Upper$“justaword”与erlang中的对应字符相比,后者并不懒惰?每当需要另一个字符(或结束通知)时,下一个字符(如果有)映射到大写,即与“W”比较,如果不相等,则传递 filter (/= 'W') . map toUpper $ "justaword" ~> filter (/= 'W') (toUpper 'j' : map toUpper "ustawo

有人能解释一下或者提供一些关于函数组合如何与懒惰相关的资源吗


例如,
如何过滤(/='W')。映射到Haskell中的Upper$“justaword”
与erlang中的对应字符相比,后者并不懒惰?

每当需要另一个字符(或结束通知)时,下一个字符(如果有)映射到大写,即与“W”比较,如果不相等,则传递

filter (/= 'W') . map toUpper $ "justaword"
~> filter (/= 'W') (toUpper 'j' : map toUpper "ustaword")
~> filter (/= 'W') ('J' : map toUpper "ustaword")
~> 'J' : filter (/= 'W') (map toUpper "ustaword")
现在第一个字符可用,因此对于像
null
这样的查询或像
take 1
这样的函数,不需要做进一步的工作。如果使用者需要更多的字符,则将逐个生成这些字符,直到到达字符串的末尾

例如:

Prelude Data.Char> take 10 . filter (/= 'W') . map toUpper $ repeat 't'
"TTTTTTTTTT"

repeat
生成一个无限列表,但只要只消耗有限部分,计算就会在有限时间内完成。但是,
取10。过滤器(/='W')。map toUpper$repeat'w'
不会终止,因为生成的字符没有一个通过
过滤器
到达
take 10

感谢您的大力响应:)是否可以用严格的语言编写此代码(不模拟惰性)?或者在严格的语言中,列表将被遍历两次,一次用于map,一次用于filter,从开头开始?@Adi:是的,将有两次列表遍历。map将返回一个新的中间列表,该列表将传递给filter,filter将传递而不是返回另一个列表。在严格的(渴望的)语言中,必须模拟懒惰才能获得相同的行为。有些语言比其他语言更容易做到这一点,我更愿意用erlang或F#而不是C(虽然我懂C,但几乎没有任何erlang或F#::)。一种语言中是否有两次遍历或一次遍历取决于编译器。原则上,过滤器和映射可以融合,但一般来说,编译器需要证明映射函数和过滤器谓词的纯度才能做到这一点。所以我希望在大多数情况下有两次遍历,证明很难。谢谢你,Daniel Fisher。我永远感激:)有兴趣的人请注意:Python的生成器主要是为了允许这种惰性处理而存在的。