2013-06-03 10 views
8

konnte ich den folgenden Code fehlerlos 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 für den folgenden Codekann nicht erwarteten Typen entspricht `einen‚mit dem tatsächlichen Typ `[a]‘

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

aber ich erhalte diese Störung auszuführen:

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

Ich bin ein Anfänger in Haskell und die Fehlermeldung ist zu griechisch und Latein für mich. Soweit ich das verstehe, kann der Compiler den Typ im zweiten Fall nicht ableiten. Kann mir jemand zeigen, was hier eigentlich passiert?

Antwort

13

Sie deklarieren die Eingabe als eine Liste des Typs [a], und der Rest ist vom Typ a.

Eine Liste des Typs a in Haskell besteht aus einem Kopf vom Typ a und einem Schwanz, eine Liste des Typs [a]. Der Konstruktor : nimmt den Kopf und den Schwanz als seine Argumente.

Wenn Sie eine Liste als (x:y), x dekonstruieren ist der Kopf und y ist der Schwanz. In Ihrem zweiten Codefragment binden Sie also die Endung der Liste, die den Listentyp [a] hat, wenn Ihre Typ-Signatur erfordert, dass Sie einen Wert vom Typ a zurückgeben (der Kopf ist ein Beispiel).

2

(_:x) entspricht _ mit dem Kopf und x mit dem Ende der Liste. Die Art des Schwanzes einer Liste ist [a]. Sie versuchen, [a] zurückzugeben, wobei die Funktionsdeklaration den Rückgabetyp als a angibt.

myLast (_:x) = x 

Wenn Sie einen Blick letztes Element nimmt an dieser Antwort entsprechen - Can you use pattern matching to bind the last element of a list?

6

ein Verständnis von dem, was : wirklich hilft ist die Fehlermeldung zu entschlüsseln. : kann als Funktion betrachtet werden, die ein Element und eine Liste nimmt, und gibt eine Liste, die, deren erstes Element das erste Argument und der Rest davon das zweite Argument ist, oder:

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

Anreise nach Ihren Funktion, schrieb Sie myLast :: [a] -> a; Der Typ myLast (_:x) = x ist jedoch myLast :: [a] -> [a], da das zweite Argument : (das Sie x benannt haben) selbst eine Liste ist.

Darüber hinaus im Allgemeinen, wenn Sie etwas in Haskell nicht verstehen, sollten Sie einen Blick auf seine Art zuerst mit :t in GHCI.

Verwandte Themen