代码之家  ›  专栏  ›  技术社区  ›  Spark Monkay

Curry匿名函数

  •  1
  • Spark Monkay  · 技术社区  · 8 年前

    我是Haskell和Functional编程的新手,有点困惑。为什么我不能使用匿名函数,或者甚至可能?

    我有以下代码:

    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.
    
    2 回复  |  直到 8 年前
        1
  •  5
  •   chi    8 年前

    | 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])
    
        2
  •  5
  •   Useless    8 年前

    x 是一个论点 largestDivisible ,但不需要将其作为参数传递给lambda。lambda可以 x 从捕获的上下文中,只需要 y 作为论据。

    第一个版本通过了部分应用 f x myFilter 并且,在给定第一个参数的情况下,这是一个一元函数。

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

    y ).