也许下面的形式更清楚:
split [] delim = [""] -- a list containing only an empty String
split (c:cs) delim = let (firstWord:moreWords) = split cs delim
in if c == delim
then "" : firstWord : moreWords
else (c:firstWord) : moreWords
该函数遍历输入字符串,将每个字符与分隔符进行比较。如果当前字符不是分隔符,则将其附加在第一个单词(可能为空)的前面,这是由于拆分字符串的其余部分而产生的,如果是分隔符,则在前面添加一个空字符串余数分割的结果。
例如,split "abc cde" ' '
收益的评估像
split "abc cde" ' '
~> 'a' == ' ' ? No, next guard
~> ('a' : something) : somethingElse
在哪里something
和somethingElse
稍后将通过拆分剩余"bc cde". After looking at the first character, it's been determined that whatever the final result is, its first entry starts with
的“a”来确定。继续确定其余部分,
split "bc cde" ' '
~> ('b' : something1) : somethingElse1
where (something1 : somethingElse1) = split "c cde" ' '
所以现在结果的第一个条目的前两个字符是已知的。然后从下一步确定以something1
开头'c'
。然后最后我们到达一个分隔符,即结果的第一个元素是在不参考以后的递归调用的情况下确定的,只有结果的其余部分在递归中被发现。
制定算法的另一种方法是(感谢@dave4420 的建议)
split input delim = foldr combine [""] input
where
combine c rest@(~(wd : wds))
| c == delim = "" : rest
| otherwise = (c : wd) : wds