2014-12-18 1 views
3

Как использовать curry и uncurry функции прелюдии в Haskell?Как вы определяете и используете curry и uncurry (функции Prelude) в Haskell?

Кроме того, почему следующие определения вызывают ошибку при загрузке?

curry' :: ((a -> b) -> c) -> a -> b -> c 
curry' f = \x y -> f (x, y) 

uncurry' :: a -> b -> c -> ((a -> b) -> c) 
uncurry' f = \(x,y) -> f x y 
+1

Ваши определения верны, вы просто сделали небольшую ошибку с типами: вы хотите перейти к/из функции, которая берет кортеж '((a, b) -> c)', а не другую функцию, как вы Теперь. Итак, '(a, b)' вместо '(a -> b)'. –

ответ

8

Вы получаете ошибки, потому что ваши сигнатуры типов являются неправильными, вы должны использовать кортежи вместо функций для аргументов 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.

+0

Мой мозговой парсер вычислен на какое-то время в последнем предложении, прежде чем реализовать структуру «это ... вместо ...». Я разбирал его как «и производит ... вместо ...». Возможно, вы можете добавить визуальную помощь для парсеров. :-) – chi