Вы получаете ошибки, потому что ваши сигнатуры типов являются неправильными, вы должны использовать кортежи вместо функций для аргументов a
и b
:
curry' :: ((a, b) -> c) -> a -> b -> c
uncurry' :: (a -> b -> c) -> ((a, b) -> c)
Также обратите внимание на круглые скобки я добавил в uncurry'
типа, в этом случае важны. Что у вас есть эквивалентно
uncurry' :: a -> (b -> (c -> ((a -> b) -> c)))
Который не то же самое, это функция, которая принимает 3 аргумента и производит функцию вместо функции, которая принимает функцию 2 аргумента и возвращает функцию одного кортежа аргумента.
Вы можете использовать эти функции, как
> uncurry (+) (1, 2)
3
> curry fst 1 2
1
> curry snd 1 2
2
(я не видел никаких других Prelude
функций, которые принимают кортежи в качестве аргументов)
EDIT: По просьбе й, вот более визуальное объяснение того, что последнее предложение:
a -> (b -> (c -> ((a, b) -> c)))
является тип функции, которая принимает 3 аргумента a
, b
и c
, и возвращает функцию типа (a, b) -> c
.
(a -> b -> c) -> ((a, b) -> c)
является тип функции, которая принимает один аргумент a -> b -> c
и возвращает функцию (a, b) -> c
.
Ваши определения верны, вы просто сделали небольшую ошибку с типами: вы хотите перейти к/из функции, которая берет кортеж '((a, b) -> c)', а не другую функцию, как вы Теперь. Итак, '(a, b)' вместо '(a -> b)'. –