Понимание функции переворота

Я изучаю функции высшего порядка из статьи "Learn You a Haskell for Great Good!" пользователя Miran Lipovaca.

Для следующей функции flip, которая принимает функцию и возвращает функцию с перевернутыми первыми двумя аргументами:

flip' :: (a -> b -> c) -> (b -> a -> c)
flip' f = g
   where g x y = f y x

Я не совсем понимаю, что такое f и g. Это две разные функции? Аналогично, что именно означает g x y = f y x в привязке where?


person ceno980    schedule 04.06.2019    source источник


Ответы (2)


В синтаксисе:

myFunction x = x + 2

вещи слева от знака равенства x рассматриваются как «параметры». Вы можете использовать их в правой части знака равенства, чтобы указать, каким должен быть результат.

Этот синтаксис определяет функцию myFunction с одним параметром x.

Итак, у нас есть:

flip' f = g

Это определяет функцию flip' с одним параметром f.

У нас есть и другое определение:

g x y = f y x

Это определяет функцию g с двумя параметрами, x и y.

Итак, когда мы говорим:

flip' f = g
  where
    g x y = f y x

Мы говорим, что результатом flip f является функция g, где g определяется как g x y = f y x.

Если вас сбивают с толку короткие имена переменных, вот та же функция с некоторыми именами, замененными для ясности:

flippity flop = glop
  where
    glop x y = flop y x

Посмотрите, можете ли вы понять, что делает flippity, и посмотрите, можете ли вы увидеть, что это то же самое, что и flip', только с другими именами внутренних параметров и вспомогательных функций.

Помните также, что в Haskell мы всегда можем заменять вызовы функций их телом по большей части. Итак, мы можем переписать это как:

flippity flop = glop
  where
    glop = \x y -> flop y x

-- replace glop with its definition

flippity flop = \x y -> flop y x

Итак, мы видим, что flippity - это функция, которая принимает функцию flop и возвращает новую функцию \x y -> flop y x.

person Justin L.    schedule 04.06.2019
comment
Вы можете сделать еще один шаг и сказать flippity flop x y = flop y x. Но это еще больше сбивало с толку. - person talex; 04.06.2019
comment
@talex не еще одним шагом будет flippity flop x = \y -> flop y x: P - person moonGoose; 04.06.2019
comment
Это настоящий детский шажок :) - person talex; 04.06.2019

f - это вход flip' (функция, которую вы хотите перевернуть), g - это результат flip's (перевернутая функция, которую он вернет).

Предложение where просто определяет, что такое g; то есть определение функции, которая просто вызывает f с обратными аргументами.

Вы можете вообще избежать именования g, просто заставив flip' вернуть лямбда:

flip' :: (a -> b -> c) -> (b -> a -> c)
flip' f = \x y -> f y x
person typedfern    schedule 04.06.2019