Подтвердить что ты не робот

Как работает функция флип?

Haskell новичок здесь. Я проходил через Учиться вам haskell, и натолкнулся на это определение функции флип.

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

Чего я не понимаю, откуда взялись х и у? Я имею в виду, что подпись говорит мне, что flip' - это функция, которая принимает функцию (с двумя параметрами) и возвращает функцию (опять же с двумя параметрами).

Если я понимаю это право, когда пишу функцию, которая выглядит как

foo :: (a -> b) -> a -> b
foo f x = f x   -- applies the function f on x

Но тогда в этом случае я передаю параметр явно [ie x], и поэтому я могу получить к нему доступ в теле функции. Итак, как получилось, что функция flip' может получить доступ к параметрам x и y?

4b9b3361

Ответ 1

Prelude, который находится в base на hackage.haskell.org, включен в неявный импорт в каждом файле Haskell, где находится функция flip. С правой стороны вы можете щелкнуть "источник" и увидеть исходный код для перевода.

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

Предложение where допускает локальные определения x=10 или y="bla". Вы также можете определять функции локально с тем же синтаксисом, что и для верхнего уровня. add x y = x + y

В приведенной ниже эквивалентной формулировке я делаю замену g = f y x

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

В настоящий момент g не принимает никаких параметров. Но что, если бы мы определили g как g a b = f b a ну, тогда мы бы имели:

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

Нет, мы можем сделать небольшое алгебраическое аннулирование (если вы думаете об этом как алгебра из математического класса, вы будете достаточно безопасны). Сосредоточение на:

flip f x y   =  g x y

Отмените y с каждой стороны для:

flip f x   =  g x

Теперь отмените x:

flip f   =  g

и теперь вернем его в полном выражении:

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

В качестве последнего косметического шага мы можем сделать замену a на x и b на y для восстановления функции до имен аргументов:

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

Как вы можете видеть, это определение flip немного кругом, и то, что мы начинаем с прелюдии, прост и является определением, которое я предпочитаю. Надеюсь, что это поможет объяснить, как работает where и как сделать небольшую алгебраическую манипуляцию кодом Haskell.

Ответ 2

flip' не имеет доступа к x и y. Он получает аргумент f и вычисляет выражение g. Нет x или y в поле зрения.

Однако g сама по себе является функцией, определяемой вспомогательным уравнением в предложении where flip'.

Вы можете читать g x y = f y x точно так же, как если бы это было уравнение верхнего уровня, например flip'. Итак, g является функцией двух аргументов, x и y. Он g имеет доступ к x и y, а не flip'. Значения для этих аргументов не существуют до тех пор, пока не будет применено значение g, и только после того, как flip' вернет функцию g (если когда-либо).

То, что особенно важно в g, которое определено в where -разделе flip', состоит в том, что оно может иметь доступ к аргументам flip', а именно, как g можно определить в терминах f.

Поэтому, когда вызывается flip', он получает функцию f. Для каждого конкретного вызова flip' он создает новую функцию g. g получит два аргумента x и y, когда он вызывается, но этого еще не произошло. flip' затем просто возвращает g в качестве результата.

Ответ 3

Найдите тип g.

Мы знаем тип флип: (a -> b -> c) -> (b -> a -> c)

Поэтому мы можем вывести тип f: (a -> b -> c)

Мы имеем это определение для g

g x y = f y x

Из правой части получаем, что y :: a и x :: b.

Следовательно, g :: b -> a -> c

Обратите внимание, что определение может быть переписано без предложения where.

flip' f = g where g x y = f y x
-> flip' f a b = g a b where g a b = f b a
-> flip' f a b = f b a

Ответ 4

Проще говоря, вы также можете определить функции в блоке where. Таким образом, переменные x и y являются только формальными параметрами g и поэтому вы можете получить к нему доступ в g x y = f y x: g x y определяет формальные параметры x и y и f y x это определение того, что делает g. Наконец, это определение возвращается из flip f = g.