2015-01-29 15 views
5

Dies ist vielleicht eine sehr grundlegende Frage, aber es scheint dennoch nicht auf SO bezogen worden zu sein.Haskell- (Typdeklaration) Was ist "a"?

Vor kurzem nahm ich Haskell und bisher gebe Erklärungen meist bestanden folgende:

Int 
Bool 
Float 
etc, etc 

nun in Listen erhalte ich, und ich bin Art Erklärungen zu sehen, dass a, wie in der folgenden Funktion verwenden dass iteriert durch eine assoziative Liste:

contains :: Int -> [(Int,a)] -> [a] 
contains x list = [values | (key,values)<-list, x==key] 

Kann jemand eine Erklärung dafür geben, was diese a ist und wie es funktioniert? Aus der Beobachtung scheint es jeden Typ zu repräsentieren. Bedeutet das, dass ich irgendeine Liste irgendeines Typs als Parameter eingeben kann?

Antwort

12

Ja, Sie haben Recht, es stellt "jeden Typ" dar - die Einschränkung ist, dass alle a s in einer gegebenen Typsignatur in denselben Typ aufgelöst werden müssen. Sie können also eine Liste beliebigen Typs eingeben, aber wenn Sie contains verwenden, um einen Wert in der Liste nachzuschlagen, muss der Wert, den Sie suchen, den gleichen Typ wie die Elemente der Liste haben - was natürlich sinnvoll ist.

+8

Ebenso wichtig ist, dass 'a' nicht speziell ist: * irgendein * Kleinbuchstabe bedeutet das. Es ist ein Typ * Variable *, und es ist möglich, dass mehrere verschiedene Typvariablen in derselben Signatur vorkommen. Zum Beispiel nimmt 'const :: a -> b -> a' zwei Argumente jedes beliebigen Typs an und gibt einen Wert mit demselben Typ wie seine erste Eingabe zurück. – amalloy

+2

Ich sehe, es ist sehr generisch. Also, ich denke, in den meisten Fällen würde "a" im Allgemeinen Elemente darstellen, die meine Funktion nicht wirklich verwendet oder zu viel verändert. – Bolboa

+1

@Bolboa: Ja, es ist eng mit dem Konzept der "Generika" in anderen Sprachen verwandt. Und ja, wenn der Typ vollständig generisch ist, gibt es wenig, was Sie direkt mit dem Wert selbst tun können. Haskell hat eine Möglichkeit, mehr Informationen über den Typ zu geben (zum Beispiel "kann für Gleichheit verglichen werden", "kann gedruckt werden", "kann wie eine Zahl behandelt werden"), wodurch Sie mehr Verarbeitung der Werte vornehmen können ; Wenn Sie daran interessiert sind, suchen Sie in der Dokumentation oder in einem Lernprogramm nach "Klassen". – psmears

1

In Haskell, sind in Großbuchstaben Typen Betontypen (Int, Bool) oder Typkonstruktoren (Maybe, Either), während Klein Typen sind Typvariablen. Eine Funktion ist implizit generisch in den alle Variablen vom Typ nutzt, so folgt aus:

contains :: Int -> [(Int, a)] -> [a] 

ist eine Abkürzung für diese *:

contains :: forall a. Int -> [(Int, a)] -> [a] 

In C++ foralltemplate geschrieben ist:

template<typename a> 
list<a> contains(int, list<pair<int, a>>); 

In Java und C# wird es mit spitzen Klammern geschrieben:

list<a> contains<a>(int, list<pair<int, a>>); 

Natürlich in diesen Sprachen sind generischer Typ Variablen oft T genannt, U, V, während in Haskell sie oft a genannt werden, b, c. Es ist nur ein Unterschied der Konvention.

* Diese Syntax wird durch das Flag -XExplicitForAll in GHC und anderen Erweiterungen aktiviert.

+0

Viel nützlicher: '-XScopedTypeVariables'. Außerdem scheinen C++ - Templates sich von Haskell/ML/... -Variablen oder sogar Java Generics zu unterscheiden. – dfeuer