2013-08-29 49 views
1

我遇到了一個問題,我認爲我可能在Haskell知識上存在差距。我試圖實現一個名爲after的函數,該函數將被賦予一個項目或一個列表,並顯示它後面的內容。在Haskell中重載通用函數

after "sample" 'a'應該返回「mple」。

after "sample" "am"應該返回「ple」。

我知道如何這兩個函數定義爲afterafterList,但我想做一個泛型函數來處理這兩個

after :: (Eq a) => [a] -> a

after :: (Eq a) => [a] -> [a]

是這樣的功能可能嗎?我在此嘗試是:

{-# LANGUAGE MultiParamTypeClasses #-} 
sub :: (Eq a) => [a] -> Int -> [a] 
sub [] _ = [] 
sub _ 0 = [] 
sub (x:xs) c = sub xs (c - 1) 

pos :: (Eq a) => [a] -> a -> Int 
pos [] _ = 0 
pos (x:xs) c 
    | x == c = 0 
    | otherwise = 1 + pos xs c 

class (Eq a) => Continuous [a] a where 
    after x c = sub x (pos x c) 

instance (Eq a) => Continuous [a] [a] where 
    after [] _ = [] 
    after x c 
    | take (length c) x == c = sub x ((length c)+1) 
    | otherwise = after (tail x) c 

但返回的

test.hs:13:28: 
    Unexpected type `[a]' where type variable expected 
    In the declaration of `Continuous [a] a' 
Failed, modules loaded: none. 

這樣的錯誤,是我的做法根本性的缺陷?怎樣才能實現泛型函數重載,帶或不帶類型類?

+0

我不知道這是否可能,我對這方面的解決方案非常感興趣。只是一個想法:我想你可以只寫afterList,並確保在函數的開頭將所有單個項目轉換爲單例列表。 – vroomfondel

回答

3

您的方法非常正確,但您需要正確寫出它。

{-# LANGUAGE FlexibleInstances  #-} 

class Continuous list part where 
    after :: list -> part -> list 

instance (Eq a) => Continuous [a] a where 
    after x c = sub x (pos x c) 

instance (Eq a) => Continuous [a] [a] where 
    after [] _ = [] 
    after x c 
    | take (length c) x == c = sub x ((length c)+1) 
    | otherwise = after (tail x) c 

請注意,儘管您的實現看起來不起作用。但他們現在進行類型檢查。

+0

這起作用。爲了使上面的代碼工作,我將子行中的行從'sub _ 0 = []'改爲'sub x 0 = x'。沒有意識到類在他們的定義中使用了這樣的通用術語。 –