【问题标题】:Haskell Question on pattern matchingHaskell关于模式匹配的问题
【发布时间】:2011-04-21 16:37:05
【问题描述】:

我正在尝试编写一个函数,它接收一个列表,如果它按排序顺序返回 true,如果不是,则返回 false:

到目前为止,我拥有的是:

myordered [] = True
myordered [x] = True
myordered list1
 | (head list1) <= (head (tail list1)) = myordered(tail list1)
 | otherwise                           = False

根据我们的分配,所有的头尾操作都应该写成“x:xs”类型的语法。

我对有警卫的部分的翻译是:

myordered y:x:xs
 | (y) <= (x) = myordered(xs)
 | otherwise  = False

基本上这个问题归结为: "x:xs" 类型语法中的 (head (tail list1)) 怎么表达?

干杯, -紫谷

【问题讨论】:

    标签: list haskell recursion pattern-matching


    【解决方案1】:

    怎么样

    isordered :: [Int] →  Bool
    isordered [] = True
    isordered xs = foldl (&&) True $ zipWith (<=) xs $ tail xs
    

    哦,只是为了好玩:

    isordered :: [Int] →  Bool
    isordered [] = True
    isordered (x:xs) = (foldl comp (Just x) xs) /= Nothing
       where comp (Just a) b = if a ≤ b then Just b else Nothing
             comp Nothing _ = Nothing  
    

    【讨论】:

      【解决方案2】:

      Data.List 中提供的zipWith 函数的帮助下,另一种方法如何?

       myordered xs= and $ zipWith (<=) xs (tail xs)
      

      zipWith 函数接受两个列表并应用一个函数。这里它将根据条件返回一个布尔数组。
      and 接受一个布尔值列表,并且仅当列表中的所有值都为 True 时才返回 True

      【讨论】:

      • 这是一个漂亮的惯用解决方案......初学者不会写。我想老师会明白的:-P
      • 我喜欢。我唯一要更改的是“drop 1”而不是“tail”,以便它适用于 []。
      • zipWith 将处理 [] ,因此 zipWith 中的尾部函数将毫无例外地工作
      【解决方案3】:

      你的模式几乎是正确的,你只需要用括号括起来:

      myordered (y:x:xs)
      

      另请注意,yx 无需在 y &lt;= x 中用括号括起来。

      您的第二个版本中也存在语义错误:

      myordered(xs)这里xs指的是尾巴的尾巴,但你想要整个尾巴,所以你应该这样做myordered (x:xs)或者:

      myordered (y:xs@(x:_))
       | y <= x = myordered xs
       | otherwise  = False
      

      其中说:xs 是该列表的尾部,x 是该尾部的头部,_(被忽略)是尾部的尾部。

      【讨论】:

      • 既然是作业,重构尾部可能更容易理解:myordered (y:x:xs) | y
      • @yatima:嗯,这是我给出的第一个选项。
      猜你喜欢
      • 2012-10-04
      • 1970-01-01
      • 1970-01-01
      • 2017-11-13
      • 2021-05-22
      • 1970-01-01
      • 1970-01-01
      • 2017-05-08
      • 1970-01-01
      相关资源
      最近更新 更多