2016-12-08 91 views
1

我是Haskell的新手,並且函數編程有點困惑。爲什麼我不能cur an一個匿名函數,或者甚至有可能?咖喱匿名函數

我有以下一段代碼:

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. 
+0

爲什麼您使用'myFilter'而不是'filter'?我認爲更合適的是使用'find'而不是'filter'。 – freestyle

回答

5

代碼

| 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]) 
+0

給你第二個代碼片段:空白是否重要?寫'\ x ...'還是'\ x ...'有區別嗎? 好吧,我想我明白了。在第三個代碼片段中,我創建了一個函數,我將其傳遞給x(您標記的x),然後通過列表。這次真是萬分感謝!顯然,第四個代碼片段將是'最好'的一個。 –

+0

@SparkMonkay'\ x'與'\ x'相同。當然'\ x y'中的空格很重要,否則'\ xy'將變量'xy'作爲參數。 – chi

+0

這就是我的意思,'\ x y z'與'\ x y z'相同。 –

5

x是一個參數largestDivisible,但你不需要將它作爲參數傳遞給你的lambda。 lambda可以從捕獲的上下文中獲得x,並且僅需要y作爲參數。

第一個版本通過部分應用f xmyFilter,並且 - 第一個參數給出 - 是一個一元函數。

第二個版本嘗試傳遞兩個參數的lambda,而不使用部分應用程序首先獲取合適的函數。

或者像第一個例子那樣使用部分應用程序,或者只寫一個參數的lambda(y)。

+0

我明白了,謝謝。很遺憾,我沒有從上下文中提取x並將其應用到函數中。 –