如何根据功能检查列表是否已订购?
> 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
答案 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)]
如果您熟悉它们,当然可以使用any
,and
等进行编码。通过列表推导,你可以在它还在学习的同时将它放在一边。
你的代码也很好,只是错过了一些括号。它应该是
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)
但有些人可能会认为这很奇怪。