为什么这两段代码的行为不一样?

时间:2012-01-23 15:21:41

标签: haskell functional-programming

为什么以下这些功能不起作用?第一个是正确的字符串拆分,但第二个似乎永远添加“”,创建一个无限列表

正确的代码:

my_split :: [Char]->Char->[[Char]]
my_split [] _ = [[]]
my_split lista y
    | notElem y lista=[lista]
    | otherwise=isMatch:(my_split rest y)
    where 
            isMatch=takeWhile (/=y) lista
            rest=tail $ dropWhile (/=y) lista

错误代码:

my_split :: [Char]->Char->[[Char]]
my_split [] _ = [[]]
my_split lista y
    | notElem y lista=[lista]
    | otherwise=isMatch:(my_split rest y)
    where 
    (isMatch,rest)=break (==y) lista

唯一不同的部分是休息条件,在我看来它应该做同样的事情......加上第一个函数表单应该确保我不会永远地为我的结果添加空列表...对于noobish问题感到抱歉,并提前致谢

3 个答案:

答案 0 :(得分:6)

GOA> break (=='c') "abcde"
("ab","cde")
GOA> break (=='c') "cde"
("","cde")
GOA> 

break不会剥离匹配的字符。

答案 1 :(得分:3)

break p xs = (takeWhile (not . p) xs, dropWhile (not . p) xs)

在您的第一个版本中,您将tail应用于dropWhile的结果。

在你的第二个版本不起作用的情况下,你不会这样做。

答案 2 :(得分:2)

正如其他人所解释的那样,break会返回一对takeWhile和dropWhile。你想抓住dropWhile的尾巴。你可以这样做:

where 
(isMatch,_:rest)=break (==y) lista