Haskell: применение флип дважды (тип флип флип) - PullRequest
0 голосов
/ 29 января 2019

Я изучаю Haskell по некоторым основным функциям.Я выполнял некоторые упражнения с Flip, который принимает функцию двух аргументов и оценивает результат, переключая порядок аргументов.Рассмотрим функцию flip flip . Я бы подумал, что после определения функции flip она дважды переключает аргументы, оценивая исходную функцию с параметрами в исходном порядке.Когда я проверил это предположение с помощью ghci, проверив тип функции, он дал:

flip flip :: b -> (a -> b -> c) -> a -> c

Iне понимаю, почему это тип функции флип-флип.Он принимает параметр b и параметр (a -> b -> c) и дает функцию a -> c.Почему это так ?Я был бы очень признателен за объяснение, так как я потерян с этим.Заранее спасибо

Ответы [ 3 ]

0 голосов
/ 29 января 2019

Вы не применяете функцию 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
0 голосов
/ 29 января 2019

Давайте рассмотрим типы:

flip :: (a -> b -> c) -> b -> (a -> c)
flip :: (d            -> e ->  f     ) -> e ->  d            ->  f
flip flip ::                              b -> (a -> b -> c) -> (a -> c)

Другими словами, flip инвертирует первые два аргумента своего аргумента, а первые два аргумента flip - это функция, которая переворачивает, иВторой аргумент этой функции.Поэтому вместо того, чтобы принимать аргументы в порядке «функция», «второй аргумент», «первый аргумент», порядок становится «вторым аргументом», «функцией», «первым аргументом», когда вы переворачиваете его.

ЕслиВы хотите, чтобы перевернуть, а затем перевернуть, вы делаете что-то вроде этого:

doubleflip x = flip (flip x)

Или эквивалентно:

doubleflip = flip . flip

Оператор (.) передает вывод правой рукив левую сторону.

0 голосов
/ 29 января 2019

Двойной щелчок будет \f -> flip (flip f) или flip . flip.Это действительно будет иметь тип (a -> b -> c) -> (a -> b -> c).

. Вместо этого вы применяете flip к функции flip, то есть переключаете порядок аргументов flip.Поэтому, если мы начнем с

flip :: (a -> b -> c) -> b -> a -> c
-- and, as the type of the argument
flip :: (a' -> b' -> c') -> b' -> a' -> c'

, тогда, если мы сопоставим типы

a = (a' -> b' -> c')
b = b'
c = a' -> c'

, мы получим результат

flip flip :: b' -> (a' -> b' -> c') -> (a' -> c')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...