2014-12-18 35 views
3

如何在Haskell中使用curryuncurry前奏功能?如何在Haskell中定義和使用curry和uncurry(Prelude函數)?

此外,爲什麼下面的定義在加載時會拋出錯誤?

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

你得到,因爲你的類型簽名是錯誤的,你應該使用的元組,而不是爲ab參數的函數錯誤:

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個函數使用元組作爲參數)

編輯:在智的要求,這裏有一個更直觀的解釋最後一句:

a -> (b -> (c -> ((a, b) -> c))) 

是,接受3個參數ab函數的類型, c,並返回(a, b) -> c類型的函數。

(a -> b -> c) -> ((a, b) -> c) 

是採用單個參數a -> b -> c並返回一個功能(a, b) -> c的功能的類型。

+0

在實現結構「這是......而不是...」之前,我的腦解析器在最後一句話上計算了一會兒。我解析它爲「併產生...而不是......」。也許你可以爲解析器添加一些視覺輔助。 :-) – chi