Вы не применяете функцию flip
дважды.Если вы хотите применить flip
дважды, вы ищете:
<b>flip . flip</b> :: (b -> a -> c) -> b -> a -> c
Что вы здесь делаете, это листание функция flip
.Таким образом, для функции flip
требуется flip
.
Мы можем разрешить тип flip<sub>1</sub> flip<sub>2</sub>
(здесь я использую подписки, чтобы прояснить, к какому flip
мы ссылаемся), как:
flip<sub>1</sub> :: (a -> b -> c) -> b -> a -> c
flip<sub>2</sub> :: (d -> e -> f) -> e -> d -> f
Поскольку flip<sub>2</sub>
является параметром flip<sub>1</sub>
, это означает, что тип flip<sub>2</sub>
совпадает с типом параметра flip<sub>1</sub>
, так что это означает:
a -> (b -> c )
~ (d -> e -> f) -> (e -> (d -> f))
Следовательно, это означает, что a ~ (d -> e -> f)
(тип a
совпадает с d -> e -> f
), b ~ e
и c ~ (d -> e)
.Таким образом, тип функции flip<sub>1</sub> flip<sub>2</sub>
является типом выходного типа flip<sub>1</sub>
, но с эквивалентностями, что означает, что:
flip<sub>1</sub> flip<sub>2</sub> :: b -> a -> c
flip<sub>1</sub> flip<sub>2</sub> :: e -> (d -> e -> f) -> (d -> e)
Таким образом, мы в основном сделали функцию, которая сначала принимаетВторой параметр, затем принимает функцию, а затем первый параметр, а затем вызывает эту функцию с перевернутыми параметрами.Так что, если flip2 = flip flip
, это реализовано так:
flip2 :: e -> (d -> e -> f) -> (d -> e)
flip2 y f x = f x y