2012-04-01 37 views
1

我想寫一個Haskell函數來檢查,如果一個整數列表是爲了在不使用任何一個已經存在的功能,訂購或檢查列表的順序列表。我寫了下面的代碼,但我不明白爲什麼它不起作用。我得到的錯誤:哈斯克爾定製isordered功能檢查整數

No instance for (Ord integer) 
     arising from a use of `<=' 
    In the expression: x <= (head xs) 

我不明白這是什麼意思。我應該寫這個函數有不同的方式嗎?這是我的代碼到目前爲止。

isordered :: [integer] -> Bool 
isordered [] = True 
isordered (x:[]) = True 
isordered (x:xs)|x <= (head xs) = isordered xs 
       |otherwise = False 

在此先感謝!

+7

它應該是'Integer',不'integer'。 – 2012-04-01 11:49:13

回答

8

在Haskell類型名稱以大寫字母和類型變量用小寫字母開頭。所以如果你寫integer,那是一個類型變量。因此,您的類型與[a] -> Bool相同,即您可以列出任何內容並返回Bool。因此,對於列表中可能包含的項目沒有限制,您不能在其上使用<=

要解決此問題,您可以將其更改爲Integer,這正是您想要的,或者添加如下所示的Ord約束:Ord a => [a] -> Bool。後者將使您的函數可以使用任何類型實現Ord類型類型(它提供比較運算符,如<=)。

+0

啊輝煌!我知道這一定是我做過的傻事! – chefburns 2012-04-01 12:00:36

3

究竟算作「已經存在的功能」?

isordered xs = all (uncurry (<=)) $ zip xs (tail xs) 

更低水平是

isordered (x:y:zs) = x <= y && isordered (y:zs) 
isordered _ = True 
+0

任何涉及排序或排序的現有庫函數都是更好的說法!在你的低級別函數中,並不總是會返回true? – chefburns 2012-04-01 12:24:27

+3

我會這樣寫:'isOrdered xs =和$ zipWith(<=)xs tail xs'來避免這種不安。 – Jedai 2012-04-01 14:12:36

+0

// @傑代:是的,看起來更好。 – Landei 2012-04-01 15:10:43

0

另一種方法使用守衛這樣做:

isOrdered :: Ord a => [a] -> Bool 
isOrdered (x:y:xs) | x<=y = isOrdered (y:xs) 
        | otherwise = False 
isOrdered _ = True