Da 1
hat Num a => a
Typ:
ghci> :t 1
1 :: Num a => a
ghci> :t kessel
kessel :: (Num b, Ord a) => a -> b -> a
ghci> :t kessel 1
kessel 1 :: (Num a, Num b, Ord a) => b -> a
ghci> :t kessel 1 2
kessel 1 2 :: (Num a, Ord a) => a
Die Einschränkungen von 1
(Num
) erhalten zu den bereits bestehenden hinzugefügt. Es ist das gleiche, wenn Sie id
verwenden, zB:
id :: a -> a
id 1 :: Num a => a
längere Erklärung
Wenn Sie kessel :: (Ord a, Num b) => a -> (b -> a)
verwenden, können Sie den Compiler sagen, dass kessel
jedea
nehmen, dass eine Instanz von Ord
ist. kessel
wird dann eine Funktion von jede andere (nicht notwendigerweise anders) Typ b
, die auch eine Instanz von Num
zu der zuvor genannten Art a
.
Dies bedeutet, dass das erste Argument Sie kessel
verwenden a
gesetzt werden:
ghci> :t kessel (1 :: Int)
kessel (1 :: Int) :: Num b => b -> Int
ghci> :t kessel 'A'
kessel 'A' :: Num b => b -> Char
ghci> :t kessel "Hello, World!"
kessel "Hello, World!" :: Num b => b -> String
In all diesen Fällen ist die Art des Arguments klar war. Was aber, wenn wir einen Wert verwenden, der polymorph ist? Zum Beispiel diese:
magic :: Magic a => a
Und lassen Sie uns auch eine einfachere Funktion, nämlich const
:
const :: a -> b -> a
const x y = x
Was ist const magic
? Beginnen wir einfacher. Was ist const "Hello, World?"
?
const :: a -> b -> a
"Hello, World?" :: String
const "Hello, World?" :: b -> String
Wir ersetzten jedes Auftreten von a
mit "Hello, World?"
‚s-Typ. Nun zurück zu unserem magic
Beispiel:
const :: a -> b -> a
magic :: Magic t => t
const magic :: Magic t => b -> t
Auch hier ersetzen wir jedes Vorkommen von a
mit unserer Art, in diesem Fall t
. Wir dürfen jedoch die zusätzliche Nebenbedingung t
, nämlich Magic
, nicht vergessen. Wir müssen es mitbringen. Daher erhalten wir hier die zusätzliche Einschränkung. Aber wenn es eine Beschränkung auf a
gibt, müssen wir sie immer noch auf t
setzen.
Gehen wir nun zurück zu Ihrem ursprünglichen kessel
:
kessel :: (Num b, Ord a ) => a -> b -> a
1 :: (Num n ) => n
kessel 1 :: (Num na, Ord na, Num b) => b -> na
Wir noch a
‚s ursprüngliche Beschränkung halten. Daher haben wir jetzt zwei Einschränkungen, Num
und Ord
. Wenn wir jetzt einen beliebigen Typ verwenden, der die Bedingung Num
erfüllt, haben wir nur noch na
. Da es nicht auf der rechten Seite ist nicht mehr, kann seine Einschränkung verworfen werden:
kessel 1 2 :: (Num na, Ord na) => na
Es wird 'Integer' wenn Sie den Compiler versichern, dass das erste Argument ein' Integer', kein '' Int' Double' usw. Also ': t kessel (1 :: Integer) 2' ist' Integer' – Michael
Warum bekomme ich nicht nur 'Num' statt' (Num a, Ord a) => a' –
Nur das erste Argument Angelegenheiten. Es muss "Ord" sein, weil du das verlangt hast. Es muss "Num" sein, weil Sie ein numerisches Literal verwendet haben. – Michael