【问题标题】:Why do these 2 pieces of code not behave identically?为什么这两条代码的行为不同?
【发布时间】:2012-01-23 15:21:40
【问题描述】:

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

正确的代码:

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

唯一不同的部分是中断条件,在我看来它确实应该做同样的事情......加上第一个函数表单应该确保我不会永远在我的结果中添加空列表......很抱歉提出这个问题并提前感谢

【问题讨论】:

    标签: haskell functional-programming


    【解决方案1】:
    GOA> break (=='c') "abcde"
    ("ab","cde")
    GOA> break (=='c') "cde"
    ("","cde")
    GOA> 
    

    break 不会删除它匹配的字符。

    【讨论】:

      【解决方案2】:
      break p xs = (takeWhile (not . p) xs, dropWhile (not . p) xs)
      

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

      在你的第二个版本不起作用时,你不要这样做。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-04-04
          • 1970-01-01
          • 1970-01-01
          • 2013-09-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多