【问题标题】:Curry Anonymous Function咖喱匿名函数
【发布时间】:2016-12-08 22:29:46
【问题描述】:

我是 Haskell 和函数式编程的新手,有点困惑。为什么我不能 curry 一个匿名函数,甚至有可能吗?

我有以下代码:

largestDivisible :: (Integral a) => a -> a
largestDivisible x
    | x <= 0    = error "NOT A VALID VALUE"
    | otherwise = head (myFilter (f x) [x-1, x-2..1])
    where f x y= x `mod` y == 0

当我尝试这样写时:

largestDivisible :: (Integral a) => a -> a
largestDivisible x
    | x <= 0    = error "NOT A VALID VALUE"
    | otherwise = head (myFilter (\ x y = x `mod` y == 0) [x-1, x-2..1])

然后,如果我尝试将其加载到 GHCi 中,则会收到以下错误:

ListStuff.hs:85:35: error:
• Couldn't match expected type ‘Bool’ with actual type ‘a -> Bool’
• The lambda expression ‘\ x y -> (mod x y == 0)’
  has two arguments,
  but its type ‘a -> Bool’ has only one
  In the first argument of ‘myFilter’, namely
    ‘(\ x y -> (mod x y == 0))’
  In the first argument of ‘head’, namely
    ‘(myFilter (\ x y -> (mod x y == 0)) [x - 1, x - 2 .. 1])’
• Relevant bindings include
    x :: a (bound at ListStuff.hs:83:19)
    largestDivisible' :: a -> a (bound at ListStuff.hs:83:1)
Failed, modules loaded: none.

【问题讨论】:

  • 你为什么用myFilter而不是filter?我认为更合适的是使用find 而不是filter

标签: haskell functional-programming currying


【解决方案1】:

代码

| otherwise = head (myFilter (f x) [x-1, x-2..1])
where f x y= x `mod` y == 0

等价于

| otherwise = head (myFilter (f x) [x-1, x-2..1])
where f = \x y -> x `mod` y == 0

相当于

| otherwise = head (myFilter ((\x y -> x `mod` y == 0) x) [x-1, x-2..1])
                                                   -- ^^^

请注意,x 的应用程序仍然存在!我们可以通过应用匿名函数(beta 步骤)进一步简化:

| otherwise = head (myFilter (\y -> x `mod` y == 0) [x-1, x-2..1])

【讨论】:

  • 第二个代码片段:空格重要吗?写\ x ... \x ...有区别吗?好吧,我想我明白了。在第三个代码片段中,我创建了一个函数,将 x(您标记的 x)传递给该函数,然后传递列表。这次真是万分感谢!显然第四个代码片段是“最好的”。
  • @SparkMonkay \ x\x 相同。 \x y 内部的空间当然很重要,否则 \xy 将变量 xy 作为参数。
  • 这就是我的意思,\ x y z\x y z 是一样的。
【解决方案2】:

xlargestDivisible 的参数,但您不需要将它作为参数传递给您的 lambda。 lambda 可以从捕获的上下文中获取x,并且只需要y 作为参数。

第一个版本将部分应用的 f x 传递给 myFilter,并且 - 给定第一个参数 - 是一元函数。

第二个版本尝试传递两个参数的 lambda,而不是先使用部分应用程序来获取合适的函数。

要么使用第一个示例中的部分应用程序,要么只编写一个参数的 lambda (y)。

【讨论】:

  • 我明白了,谢谢。很遗憾我没有从上下文中取出 x 并将其应用到函数中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 2011-04-21
  • 2013-08-26
  • 1970-01-01
相关资源
最近更新 更多