【问题标题】:How do you define and use curry and uncurry (Prelude functions) in Haskell?你如何在 Haskell 中定义和使用 curry 和 uncurry(Prelude 函数)?
【发布时间】:2014-12-18 19:32:10
【问题描述】:

如何在 Haskell 中使用 curryuncurry 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

【问题讨论】:

  • 你的定义是正确的,你只是在类型上犯了一个小错误:你想去/从一个接受元组((a, b) -> c)的函数而不是你现在拥有的另一个函数。所以(a, b) 而不是(a -> b)

标签: haskell currying


【解决方案1】:

您收到错误是因为您的类型签名错误,您应该为 ab 参数使用元组而不是函数:

curry' :: ((a, b) -> c) -> a -> b -> c
uncurry' :: (a -> b -> c) -> ((a, b) -> c)

另外,请注意我添加到uncurry's 类型的括号,这些在这种情况下很重要。你所拥有的就相当于

uncurry' :: a -> (b -> (c -> ((a -> b) -> c)))

不同的是,这是一个接受 3 个参数并生成一个函数的函数,而不是一个接受 2 个参数并返回一个元组参数的函数的函数。

你可以像这样使用这些函数

> uncurry (+) (1, 2)
3
> curry fst 1 2
1
> curry snd 1 2
2

(我没有看到任何其他将元组作为参数的Prelude 函数)

编辑:应 chi 的要求,这里是对最后一句话的更直观的解释:

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

是一个函数的类型,它接受 3 个参数 abc,并返回一个类型为 (a, b) -> c 的函数。

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

是接受单个参数a -> b -> c 并返回函数(a, b) -> c 的函数的类型。

【讨论】:

  • 我的大脑解析器在最后一句话上计算了一段时间,然后才意识到结构“这是……而不是……”。我将其解析为“并产生......而不是......”。也许您可以为人类解析器添加一些视觉辅助。 :-)
猜你喜欢
  • 1970-01-01
  • 2012-01-13
  • 2016-08-28
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 2017-06-27
  • 1970-01-01
  • 2017-11-15
相关资源
最近更新 更多