2013-06-03 19 views
8

udało mi się wykonać następujący kod bezbłędnieNie można dopasować oczekiwany typ `a„z rzeczywistego typu `[a]”

myLast :: [a] -> a 
myLast [] = error "Can't call myLast on an empty list!" 
myLast (x:_) = x 

ale dostaję ten błąd Couldn't match expected type `a' with actual type `[a]'. `a' is a rigid type variable bound by the type signature for myLast :: [a] -> a z następującego kodu:

Jestem początkujący w Haskell, a komunikat o błędzie jest zbyt grecki i łaciński dla mnie. Z tego, co rozumiem, kompilator nie jest w stanie wnioskować o typie w drugim przypadku. Czy ktoś może mnie wskazać na to, co się tutaj dzieje?

Odpowiedz

13

Deklarujesz wejście jako listę typu [a], a reszta ma być typu a.

Lista typu a w Haskell składa się z głowy typu a i ogona, listy typu [a]. Konstruktor cons kusi : jako argumenty przyjmuje głowę i ogon.

Po dekonstrukcji listy jako (x:y), x jest głową, a y jest ogonem. Więc w drugim fragmencie kodu wiążesz ogon z listy, która ma typ listy [a], kiedy twój podpis typu wymaga, abyś zwrócił wartość typu a (głowa jest jednym z przykładów).

6

Mając zrozumienie tego, co naprawdę jest : pomoże odszyfrować komunikat o błędzie. : można traktować jako funkcję, która bierze elementu oraz listy i zwraca listę, której pierwszym elementem jest pierwszym argumentem, a reszta to drugi argument, czyli

(:) :: a -> [a] -> [a] 

dotarcie do funkcja, napisałeś: myLast :: [a] -> a; jednak typ myLast (_:x) = x jest myLast :: [a] -> [a], ponieważ drugi argument : (który został nazwany x) sam jest listą.

Dodatkowo, jeśli czegoś nie rozumiesz w Haskell, powinieneś najpierw sprawdzić, czy jest to typ :t w GHCI.

Powiązane problemy