检查列表是否按功能排序

时间:2016-06-05 23:37:53

标签: haskell

如何根据功能检查列表是否已订购?

> ordered (<) [1,2,3,4,5]
True
> ordered (<) [5,4,3,2,1]
False
> ordered (>) [5,4,3,2,1]
True

我试着写这样的东西,但它没有用 - 这段代码有什么不对?

ordered :: (Ord a) => (a -> a -> Bool) -> [Integer] -> Bool
ordered f [] = True
ordered f [a] = True
ordered f (x1:x2:xs) =
    if ((f) x1 x2)
        then ordered f [x2]++xs
        else False

5 个答案:

答案 0 :(得分:6)

你得到的错误是双重的 - 第一次错误

$ > ghci tmp.hs
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Main             ( tmp.hs, interpreted )

tmp.hs:8:14:
    Couldn't match expected type ‘[Integer]’ with actual type ‘Bool’
    In the first argument of ‘(++)’, namely ‘ordered f [x2]’
    In the expression: ordered f [x2] ++ xs

tmp.hs:8:14:
    Couldn't match expected type ‘Bool’ with actual type ‘[Integer]’
    In the expression: ordered f [x2] ++ xs
    In the expression:
      if ((f) x1 x2) then ordered f [x2] ++ xs else False
    In an equation for ‘ordered’:
        ordered f (x1 : x2 : xs)
          = if ((f) x1 x2) then ordered f [x2] ++ xs else False
Failed, modules loaded: none.

基本上说您尝试将(++)运算符应用于两个不同的列表 - 因为ordered f [x2] :: [Bool]xs :: [Integer]

要修复它 - 您只需要添加大括号ordered f ([x2] ++ xs)

编译这会导致另一个错误

$ >  ghci tmp.hs
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Main             ( tmp.hs, interpreted )

tmp.hs:7:13:
    Couldn't match expected type ‘a’ with actual type ‘Integer’
      ‘a’ is a rigid type variable bound by
          the type signature for
            ordered :: Ord a => (a -> a -> Bool) -> [Integer] -> Bool
          at tmp.hs:3:12
    Relevant bindings include
      f :: a -> a -> Bool (bound at tmp.hs:6:9)
      ordered :: (a -> a -> Bool) -> [Integer] -> Bool
        (bound at tmp.hs:4:1)
    In the first argument of ‘f’, namely ‘x1’
    In the expression: ((f) x1 x2)
Failed, modules loaded: none.

表示ghc无法与具体类型Ord a的任何Integer匹配。

修复方法是将类型签名更改为以下

ordered :: Ord a => (a -> a -> Bool) -> [a] -> Bool

侧面说明 - 可以使用函数

简化算法
  • and
  • zipWith
  • tail
  

ordered f xs = and $ zipWith f xs (tail xs)

答案 1 :(得分:2)

使用列表推导,它可以是

ordered f xs = null [() | (a,b) <- zip xs (drop 1 xs), not (f a b)]

如果您熟悉它们,当然可以使用anyand等进行编码。通过列表推导,你可以在它还在学习的同时将它放在一边。

你的代码也很好,只是错过了一些括号。它应该是

       then ordered f ( [x2]++xs )

顺便说一句,只是说

  

不起作用 - 这段代码有什么问题?

还不够。当然,您已尝试加载此代码,并收到错误消息,谈论“类型不匹配”,甚至向您显示相关表达式,

    In the expression: ordered f [x2] ++ xs
    In the expression:
      if ((f) x1 x2) then ordered f [x2] ++ xs else False
    In an equation for `ordered':
        ordered f (x1 : x2 : xs)
          = if ((f) x1 x2) then ordered f [x2] ++ xs else False

这可能提供了线索。在Haskell中,函数应用程序(仅表示并置,即空格)具有最高优先级,因此您的代码被解释为(ordered f [x2]) ++ (xs)

答案 2 :(得分:2)

另一种选择

ordered f a = and $ zipWith f a (tail a)

答案 3 :(得分:1)

一个不使用内置函数的解决方案(是的,它正在重新发明轮子),但提供了一些如何解决这些问题的见解如下:

getTableView().requestFocus();
getTableView().scrollTo(rowToEdit);
getTableView().layout();
// getTableView().edit goes here.

答案 4 :(得分:0)

我个人这样写:

ordered f xs = foldr go (`seq` True) xs Nothing
  where
    go x r Nothing = r (Just x)
    go x r (Just prev) = f prev x && r (Just x)

但有些人可能会认为这很奇怪。