【问题标题】:Defining addition using unary functions and currying in Haskell?在 Haskell 中使用一元函数和柯里化定义加法?
【发布时间】:2014-04-14 15:13:21
【问题描述】:

我是一个试图理解柯里化的 Haskell 初学者。 我已经看到应该演示它的示例,但它们涉及二元运算符,它们本身是柯里化的,使我陷入无限递归。 如果 Haskell 中的运算符是函数,并且所有函数都是一元和柯里化的,我是否可以仅根据一元函数定义自己的加法函数?

【问题讨论】:

标签: haskell currying


【解决方案1】:

是的。

add :: Num a => a -> a -> a
add = \a -> \b -> a + b

这也是一个闭包的例子。 \b -> a + b 可以通过闭包访问 a,因为 a 是在该 lambda 范围之外定义的。

编辑

这些被称为皮亚诺数值

data Nat = Zero | Succ Nat                   

add Zero = \n -> n                                                              
add (Succ a) = \b -> Succ (add a b)                                             

toNat 0 = Zero                                                                  
toNat n = Succ (toNat (n-1))                                                    

fromNat Zero = 0                                                                
fromNat (Succ n) = 1 + fromNat n  


λ: fromNat $ add (toNat 3) (toNat 4)
7

【讨论】:

  • 这对我来说似乎有点循环推理,就像我在我的问题中提到的例子一样......这并不能解释太多......
  • 您说的是+ 运算符还是lambda?
  • 我对如何首先实现 + 感兴趣。
  • @user3026691:在这种情况下,您的问题具有误导性,实际上应该类似于“(+) 如何在标准类型的 Haskell 中实现?”。
  • @DiegoNolan 再次用加法来定义加法是一种更冗长的方式......
【解决方案2】:

haskell 中的函数是一元的,只是因为它们看起来是一元的。 用户。 Haskell 语言对这些函数的实现只字未提。 将 (+) 实现为 haskell 实现是完全可以的 二进制函数,如果它还提供某种方式来表示像(+) 2 这样的值。通常 这是通过捆绑二进制函数和参数列表来完成的,在本例中为2

如果你真的想用一元函数来实现 (+),你可以 做类似的事情:

plus a b
    | a > 0 = plus (pred a) (succ b)
    | a < 0 = plus (succ a) (pred b)
    | otherwise = b

但我认为这对您更好地理解 Haskell(或 Haskell 实现)没有任何帮助。

【讨论】:

  • 我意识到实际的 Haskell 加号运算符可能归结为一些带有两个操作数的加法指令。我实际上在寻找,并且能够从您和 DiegoNolan 的答案中收集到的是:add 0 = \a -&gt; a add b = \a -&gt; succ (add a (pred b)) add 3 4 这清楚地表明 add 是一个返回另一个一元函数的一元函数。当我看到这样的内容时:add = \a -&gt; \b -&gt; a + b 我只需要接受作者的话,add 实际上并不只是返回一个二进制函数。
  • 好吧,我想我有点没抓住重点。但是,可能值得注意的是,函数的数量不依赖于定义中提到的变量的数量。所以add = (+)add a = (+) aadd a b = (+) a b 都具有相同的类型。
【解决方案3】:

如果您想使用 curry 添加元组,请使用以下代码:

addPair  :: Num a => (a,a) -> a    
addPair  = \(a ,b) -> a + b

即函数中没有传递任何参数。

【讨论】:

    猜你喜欢
    • 2011-04-22
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-16
    • 2016-01-01
    • 2019-12-07
    • 2018-02-05
    相关资源
    最近更新 更多