2017-09-07 5 views
1

Dies ist wahrscheinlich eine dumme Frage, aber ich würde gerne Typ Signaturen besser verstehen und warum bekomme ich den folgenden Fehler, wenn ich meinen Code ausführen. Code ist unten.Typ Unterschrift Fehler Haskell

area :: Double d => d -> d 
area x = x^2 * 3.14 

Der Fehler, den ich bekomme, ist unten.

Double is applied to too many type arguments 
In the type signature for `area': area :: Double d => d -> d 
+2

'Double' ist ein' Baumuster zur, aber Sie verwenden es, als ob es waren eine 'typeclass'. Siehe [hier] (http://learnyouahaskell.com/types-and-typeclasses). – hnefatl

+0

Ok, das hat geholfen. –

+1

Mögliches Duplikat von [\ 'String 'wird auf zu viele Typargumente angewendet] (https://stackoverflow.com/questions/12018959/string-is-applied-to-too-many-type-arguments), [Typen: (Num a, Ord a) gegen (Int a)?] (Https://stackoverflow.com/questions/16329408/types-num-a-ord-a-versus-int-a). – amalloy

Antwort

5

Die Signatur Sie wollen, ist Double -> Double.

Double d => d -> d sagt „Ich habe einen Wert von jeder Art nehmen d und geben einen Wert des gleichen Typs, vorausgesetzt, dass d eine Instanz eines typeclass genannt hat Double“. Der Compiler sucht nach einer Typenklasse namens Double, aber es gibt keine solche Typklasse; Stattdessen findet es einen Typ namens Double, der einen Fehler gibt.

mit einigen Erweiterungen (wie TypeFamilies oder GADTs) Sie können diese Art schreiben wie folgt:

(d ~ Double) => d -> d 

Dies sagt: „Ich nehme einen Wert von jeder Art d und geben einen Wert desselben Typ, vorausgesetzt, dass d gleich Double ist ". Das ist nur ein Umweg zu sagen Double -> Double; Wenn Sie eine Funktion dieser Art zu schreiben, wird der Compiler tatsächlich erweitern, um Double -> Double:

> :set -XTypeFamilies 
> let f :: (d ~ Double) => d -> d; f x = x 
> :t f 
f :: Double -> Double 

Technisch, der Fehler, den Sie angetroffen haben, ist eine Art Fehler-Arten die „Art von Typen“ sind und werden verwendet, um Dinge wie die richtige Anzahl von Typparametern einem Typ zu geben. Da Sie einen Typparameter an Double geben, schließt GHC, dass es eine Typklasse wie Eq oder Ord sein sollte, die 1 Typ als Argument (Art * -> Constraint) nimmt, aber Double ist ein einfacher Typ, der keine Argumente (Art *) nimmt. Sie können mit dem :kind oder :k Befehl, um die Arten von gängigen Typen & typeclasses in GHCi sehen ein besseres Verständnis davon zu bekommen:

> :k Double 
Double :: * 

> :k Maybe 
Maybe :: * -> * 

> :k Maybe Double 
Maybe Double :: * 

> :k Eq 
Eq :: * -> Constraint 
+0

Ich finde das ganze Gerede über Arten in dieser Antwort überflüssig und wahrscheinlich ziemlich verwirrend für das OP, unter Berücksichtigung des Grundlevels der Frage. – luqui

+1

@luqui: Ich fand es hilfreich, ziemlich früh auf meiner Haskell-Reise etwas über Arten zu lernen, aber ich weiß es zu schätzen, dass es vielleicht nicht für alle gleich hilfreich ist. Ich habe diese Informationen in einen separaten Abschnitt aufgeteilt und weitere Erklärungen hinzugefügt, in der Hoffnung, dass es zumindest klarer ist. –