2016-04-13 15 views
1

Ich bin dabei, ein Projekt in Haskell zu erstellen, wo ich eine Funktion erstellen möchte, die zwei Listeneingaben und dann eine Union der Liste zurückgibt aber ohne Duplikate.Haskell "Konnte nicht den erwarteten Typ 'a' mit dem tatsächlichen Typ '[a0]'"

Das Problem ist, dass ich die Fehlermeldung erhalte:

Couldn't match expected type ‘a’ with actual type ‘[t0]’ 
     ‘a’ is a rigid type variable bound by 
      the type signature for newList :: [a] -> [a] -> [a] 

Hier ist mein Code:

allList :: (Eq a) => [a] -> [a] -> [a] 
allList [] [] = [] 
allList x y = (x ++ y) 

checkDup [] = [] 
checkDup (z:zs) 
    | z `elem` zs = checkDup zs 
    | otherwise = z : checkDup zs 

newList :: (Eq a) => [a] -> [a] -> [a] 
newList [] [] = [] 
newList x y = [checkDup z | z <- allList x y] 

Die erste allList Funktion erstellt eine Liste der beiden Liste, die checkDup schafft ein neue Liste ohne Duplikate und die newList verwendet Listenverständnis, um die kombinierte Liste an die checkDup zu übergeben.

Wer weiß, wo ich falsch liege?

+1

Drei kleinere Notizen, die ich hoffe, Sie Haskell lernen helfen: 1) 'allList' und' newList' benötigen keine ersten Fälle. 2) Sie brauchen 'Eq' nicht für die Mustererkennung, so dass' allList' nicht unbedingt die 'Eq a'-Bedingung benötigt. 3) Wenn Sie den unnötigen Code entfernen, den ich erwähnt habe, dann ist 'allList' einfach ein Alias ​​für' (++) '. Sie könnten 'x ++ y' anstelle von' allList xy' in 'newList' schreiben und die' allList' Funktion löschen (es sei denn, die Übung erfordert es irgendwie, sie zu definieren und zu benutzen, oder wenn Sie denken, dass der Code lesbarer ist es). –

Antwort

3

Das Problem liegt hier:

newList x y = [checkDup z | z <- allList x y] 

z soll eine Liste, die Sie checkDup passieren sein, aber in diesem Fall z ist nur ein einziges Element

Vielleicht Sie wollen:

newList x y = checkDup $ allList x y 

newList kann wie folgt deklariert werden:

newList :: (Eq a) => [a] -> [a] -> [a] 
newList = checkDup . allList 
+0

Danke, es funktioniert jetzt! :) –

+0

Bitte schreiben Sie immer Leerzeichen um den Kompositionsoperator. Wenn nicht, sieht es zu sehr nach Namensqualifikation aus. –

0

Da @ Smac89 Ihre Frage beantwortet hat, warum nicht eine Datendarstellung wie Data.Set verwenden?

import qualified Data.Set as S 

allList :: Ord a => [a] -> [a] -> [a] 
allList xs ys = S.toList $ S.union (S.fromList xs) (S.fromList ys) 

(., Obwohl die weitere Verwendung von Set s wahrscheinlich noch sinnvoll ist)

oder mit Data.List:

import Data.List 

newList :: Eq a => [a] -> [a] -> [a] 
newList xs ys = nub $ xs ++ ys 
+0

Ja normalerweise würde ich aber es ist für ein Schulprojekt und wir dürfen keine Importe verwenden. –

Verwandte Themen