Ray*_*yne 2 recursion haskell functional-programming lazy-evaluation
我过去曾经涉足过Haskell,最近又认真地回到了它,我正在阅读真实的世界.他们已经发光的一些例子,我还没有理解.在这一个:
myLength [] = 0
myLength (x:xs) = 1 + myLength (xs)
Run Code Online (Sandbox Code Playgroud)
我不知道这是如何工作的,真正添加的是什么?递归如何返回可以添加的内容?我不明白.
在这里我们有这个:
splitLines [] = []
splitLines cs =
let (pre, suf) = break isLineTerminator cs
in pre : case suf of
('\r':'\n':rest) -> splitLines rest
('\r':rest) -> splitLines rest
('\n':rest) -> splitLines rest
_ -> []
isLineTerminator c = c == '\r' || c == '\n'
Run Code Online (Sandbox Code Playgroud)
这是如何工作的,什么是真正的附加呢?我没有看到case表达式的结果是如何预先连接到的.也许我只需要有人详细解释这些功能的评估.我必须遗漏一些非常重要的东西.
提前致谢!
编辑:我知道,这是一个复制粘贴失败.抱歉.
编辑2:似乎我的困惑在于这些功能实际/返回/我现在已经解决了.谢谢你们的答案,终于点击了!我很感激!
wax*_*ing 10
至于第一个,它是一种非常基本的递归方式.但是,似乎缺少一部分:
myLength [] = 0
Run Code Online (Sandbox Code Playgroud)
它的工作原理是从列表中缩小一个元素并将一个元素添加到结果中.要想象,请考虑通话
myLength [1,2,3]
Run Code Online (Sandbox Code Playgroud)
将评估为:
1 + myLength [2,3]
1 + 1 + myLength [3]
1 + 1 + 1 + myLength []
1 + 1 + 1 + 0
Run Code Online (Sandbox Code Playgroud)
这是3.
至于第二个,嗯,你已经把下一个换行符的字符串分成两个部分:pre和suf.现在,suf将以\n,\n或\ r或\ r \n开头.我们想删除这些.所以我们使用模式匹配.看看rest变量本质上是suf变量减去初始换行符.
所以我们有pre,这是第一行,rest,这是文本的其余部分.因此,为了继续将休息分成行,我们以递归方式调用splitLines并将结果连接到pre.
要想象,请说你有字符串"foo \nbar\r \n \nbaz".
所以,在调用时,结果将是:
[ pre => foo, suf => \nbar\r\nbaz, rest => bar\r\n\baz ]
foo : splitLines bar\r\nbaz
Run Code Online (Sandbox Code Playgroud)
然后再次调用splitLines,结果扩展为:
[ pre => bar, suf => \r\nbaz, rest = baz ]
foo : bar : splitLines baz
Run Code Online (Sandbox Code Playgroud)
再一次:
[ pre => baz, suf => [], rest = [] ]
foo : bar : baz
Run Code Online (Sandbox Code Playgroud)
这是最后的结果.