【问题标题】:difficult to understand function definition难以理解的函数定义
【发布时间】:2016-01-05 00:32:23
【问题描述】:
cube (x,y,z) =
  filter (pcubes x) cubes


cubes = [(a,b,c) | a <- [1..30],b <- [1..30],c <- [1..30]]


pcubes x (b,n,m) = (floor(sqrt(b*n)) == x)

所以这段代码可以工作,cubes 生成一个元组列表,pcubes 与过滤器一起使用来过滤所有满足floor(sqrt(b*n)) == x 的立方体,但是修改我代码的人在@987654326 中写了pcubes x @,这是如何工作的。pcubes x 制作了一个函数,该函数将初始化 cubes x (b,n,m),它将接收一个元组并输出一个布尔值。该布尔值将用于过滤器函数。这种操纵是如何发生的? pcubes x如何访问(b,n,m)部分函数?

【问题讨论】:

  • 我不确定你具体是什么感到困惑。哪个x在哪里?
  • 坚持编辑问题
  • 我建议重新表述问题,以便更清楚您期望代码做什么。另外我建议您添加类型签名。他们可能会指出奇怪的事情,例如 cube[(a,b,c)] 类型,而 cubes 也是 [(a,b,c)]。虽然这可能是有意为之,但我找不到这段代码背后的任何直觉(我没有说这意味着什么)。

标签: function haskell functional-programming currying


【解决方案1】:

在 Haskell 中,我们通常不使用元组(即:(a,b,c))将参数传递给函数。我们使用currying

这是一个例子:

add a b = a + b

这里add是一个接受数字的函数,返回另一个接受数字的函数,然后返回一个数字。我们将它的类型表示为:

add :: Int -> (Int -> Int)

由于-&gt; 的行为方式,我们可以在这种情况下删除括号:

add :: Int -> Int -> Int

它是这样称呼的:

(add 1) 2

但由于应用程序的工作方式,我们可以写:

add 1 2

这看起来不像我们上面的定义,形式为add a b...?


你的函数pcubes 是类似的。我是这样写的:

pcubes x (b,n,m) = floor (sqrt (b*n)) == x

正如其他人所说,它的类型可以表示为:

pcubes :: Float -> (Float, Float, Float) -> Bool 

当我们写pcubes 1 时,类型变为:

pcubes 1 :: (Float, Float, Float) -> Bool

通过柯里化,这是合法的,并且可以很高兴地在其他地方使用。

我知道,这对我来说是一种疯狂的黑色函数魔法,但我保证你永远不会想回去:柯里化函数很有用。


关于元组的注释:像(a,b,c) 这样的表达式是数据。它们不是纯粹的函数参数表达式。我们可以将其拉入函数的事实称为 模式匹配,虽然轮不到我参与。

【讨论】:

    猜你喜欢
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多