Три типа ...
type T1 a = (a -> a) -> (a -> a -> a)
type T2 a = a -> a -> ((a -> a) -> a)
type T3 a = a -> a -> (a -> (a -> a))
... действительно различны. Однако T1
и T2
эквивалентны в том смысле, что между ними существует изоморфизм, который сводится к изменению порядка аргументов:
GHCi> :info T1
type T1 a = (a -> a) -> a -> a -> a
-- Defined at <interactive>:12:1
GHCi> :info T2
type T2 a = a -> a -> (a -> a) -> a
-- Defined at <interactive>:13:1
GHCi> :t flip
flip :: (a -> b -> c) -> b -> a -> c
GHCi> :t (flip .)
(flip .) :: (a1 -> a2 -> b -> c) -> a1 -> b -> a2 -> c
GHCi> f = (flip .) . flip
GHCi> :t f :: T1 a -> T2 a
f :: T1 a -> T2 a :: T1 a -> T2 a
GHCi> g = flip . (flip .)
GHCi> :t g :: T2 a -> T1 a
g :: T2 a -> T1 a :: T2 a -> T1 a
Затем мы можем показать, что f
и g
являются обратными (т.е. g . f = id
и f . g = id
):
f . g
(flip .) . flip . flip . (flip .)
(flip .) . (flip .) -- flip . flip = id
id -- (flip .) . (flip .) = \h -> \x -> flip (flip (h x)) = \h -> \x -> h x = id
g . f
flip . (flip .) . (flip .) . flip
flip . flip
id