Definicja curry
jest:
curry :: ((a, b) -> c) -> a -> b -> c
curry f = \x y -> f (x, y)
Jeśli podstawimy że:
\x y z -> (curry (==) x y) z
\x y z -> ((==) (x, y)) z -- Function application
\x y z -> (==) (x, y) z -- Remove parentheses (function application is left associative in Haskell, so they are unnecessary here)
\x y z -> (x, y) == z -- Convert to infix
Możemy powiedzieć od razu, że z
musi być jakiś z krotki, albo też ta ostatnia linia nie sprawdzi sprawdzenia, ponieważ oba argumenty to ==
musi mieć ten sam typ.
Kiedy patrzymy na definicji instancji krotki dla Eq
znajdujemy
instance (Eq a, Eq b) => Eq (a, b) where
(x, y) == (x', y') = (x == x') && (y == y')
(to nie jest napisane w kodzie źródłowym biblioteki standardowej, to w rzeczywistości wykorzystuje „autonomiczną wynikających” mechanizm automatycznego uzyskania instancję dla typu (Eq a, Eq b) => (a, b)
. Kod ten jest odpowiednikiem tego, co dostaje pochodzi choć.)
tak więc, w tym przypadku, możemy traktować ==
jakby to ma typ
(==) :: (Eq a, Eq b) => (a, b) -> (a, b) -> Bool
Zarówno x
i y
musi mieć typy, które są instancjami Eq
, ale nie muszą być wystąpienie Eq
samo. Na przykład, co jeśli mamy 12
i "abc"
? Są to dwa różne typy, ale nadal możemy korzystać z naszej funkcji, ponieważ oba są instancjami Eq
: (\x y z -> (x, y) == z) (12, "abc") (30, "cd")
(ten typ wyrażeń sprawdza i ocenia na False
).
OK, ale jak się zorientowaliście, że == zostało zastosowane do krotek? – Fof
@Seba Ponieważ 'curry' oczekuje funkcji, której pierwszym argumentem jest krotka. – sepp2k