2017-02-21 6 views
2

Ich habe folgende Art Signatur:Warum der Typ Char ist -> Char -> Char

*Main Lib> let f :: a -> a -> a -> a; f = undefined 
*Main Lib> let x :: Char; x = undefined 

so, um herauszufinden, welche bekommen würde ich Art zur Folge haben, ich habe:

*Main Lib> :t f x 
f x :: Char -> Char -> Char 

Warum nicht

Char -> Char -> Char -> Char 

Wegen des ersten Parameters ist bereits mit x substituierte?

+0

Da die Art der Funktionsanwendung ist '(a -> b) -> a -> b ', nicht' (a - > b) -> a -> (a -> b) '. – user2407038

Antwort

3

Ja, genau. Betrachten Sie eine andere Funktion, length :: [a] -> Int. Wenn Sie die Art von length "abc" fragen, erhalten Sie Int:

Prelude> :t length "foo" 
length "foo" :: Int 

Im Allgemeinen, wenn Sie eine Funktion f :: A -> B und ein Argument haben x :: A, dann f x :: B.

In Ihrem Fall haben wir f :: a -> (a -> a -> a) (spezialisiert auf a = Char), so A = Char und B = Char -> Char -> Char.

(a -> a -> a -> a ist die gleiche wie a -> (a -> a -> a) weil -> in rechten assoziativ ist.)

+0

Vielen Dank für Ihre Hilfe. –

2

Es ist, weil f x ist die Funktion f mit seinem ersten Parameter bereits angewendet, so dass es nur zwei weitere benötigt, um das Ergebnis zu erhalten. Dies nennt man currying.

In Haskell gibt es nicht wirklich eine Funktion mit drei Parametern. a -> a -> a -> a bedeutet "Eine Funktion, die eine a nimmt und eine Funktion zurückgibt, die eine a nimmt und eine Funktion zurückgibt, die eine a nimmt und eine a zurückgibt".

Das ist eine Menge von einem Mund zu schreiben, so einfach einige Parens setzen und es wird klarer: a -> (a -> (a -> a)).

So f x gibt Ihnen a -> (a -> a). Es passiert einfach, dass die Haskell-Syntax f x y z lautet und sich so verhält, als würde man eine Funktion mit drei Parametern aufrufen, und der Compiler ist schlau genug, all diese Zwischen-Curry-Funktionen nicht zu konstruieren, wenn es nicht nötig ist.

Verwandte Themen