Можно ли использовать унарную функцию вместо двоичной в `flip`?

Тип функции Prelude flip:

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

I.e., он принимает одну двоичную функцию и два аргумента.

Тип функции Prelude id:

id :: a -> a

Но тип flip id:

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

Как можно применить flip к id, когда id является унарной функцией, а flip требуется двоичная функция для первого arg?

кстати. flip id похож на \ x f -> f x

Ответ 1

Haskell делает id подходящим типом первого аргумента для flip, установив a = b -> c. Итак:

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

где id считается типом

id :: (b -> c) ->  b -> c

что эквивалентно

id :: (b -> c) -> (b -> c)

то есть. специализация id, которая применяется только к унарным функциям.

Изменить: я думаю, что я мог бы перефразировать мою первую строку как:
Haskell выводит, что id соответствует типу первого аргумента flip, если a = b -> c.
В случае, если все четче.

Ответ 2

Nefrubyr объясняет это очень хорошо.
Еще один способ (надеюсь) сделать это немного интуитивным - подумать о приложении приложения функций ($).

($) является специализированной формой id:

($) :: (a -> b) -> (a -> b)
($) = id

Я видел определение (#) = flip ($), так что вы можете написать аргумент перед применяемой функцией: obj # show.

Очевидно, что поскольку ($) является только специализированной формой id, вы также можете написать: (#) = flip id