Curry 匿名函数
Curry Anonymous Function
我是 Haskell 和函数式编程的新手,有点困惑。为什么我不能柯里化匿名函数,或者甚至可能?
我有如下一段代码:
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.
x
是 largestDivisible
的参数,但您不需要将其作为参数传递给您的 lambda。 lambda 可以从捕获的上下文中获取 x
,并且只需要 y
作为参数。
第一个版本将部分应用的 f x
传递给 myFilter
,并且 - 给出第一个参数 - 是一元函数。
第二个版本尝试传递一个包含两个参数的 lambda,而不是首先使用部分应用程序来获取合适的函数。
要么像第一个示例那样使用部分应用程序,要么只编写一个参数的 lambda (y
)。
代码
| 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
的应用程序仍然存在!我们可以通过应用匿名函数(测试步骤)进一步简化:
| otherwise = head (myFilter (\y -> x `mod` y == 0) [x-1, x-2..1])
我是 Haskell 和函数式编程的新手,有点困惑。为什么我不能柯里化匿名函数,或者甚至可能?
我有如下一段代码:
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.
x
是 largestDivisible
的参数,但您不需要将其作为参数传递给您的 lambda。 lambda 可以从捕获的上下文中获取 x
,并且只需要 y
作为参数。
第一个版本将部分应用的 f x
传递给 myFilter
,并且 - 给出第一个参数 - 是一元函数。
第二个版本尝试传递一个包含两个参数的 lambda,而不是首先使用部分应用程序来获取合适的函数。
要么像第一个示例那样使用部分应用程序,要么只编写一个参数的 lambda (y
)。
代码
| 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
的应用程序仍然存在!我们可以通过应用匿名函数(测试步骤)进一步简化:
| otherwise = head (myFilter (\y -> x `mod` y == 0) [x-1, x-2..1])