2014-07-08 62 views
3

假設部分應用功能的n次

f x y z = x*y*z 

然後,我期待與列表

foldl ($) f [1,2,3] 

喜歡的東西(((f 1) 2) 3) = 1*2*3 = 6

功能的每個成員返回F的三倍應用f將是累加器,並且每次迭代將應用一個參數並返回一個部分應用的函數作爲下一個累加器。

爲什麼不能正常工作?是否因爲f在迭代時更改類型?

順便說一句:有沒有其他的方法來完成這種類型的函數應用程序?

+1

可能的重複[如何定義Lisp在Haskell中的應用?](http://stackoverflow.com/questions/6168880/how-do-i-define-lisp-s-apply-in-haskell) –

+5

As一個非常微不足道的反例,可以考慮'foldl($)f [1,2,3,4]'。這顯然是錯誤的,所以如果你想'foldl($)f [1,2,3]'來檢測和foldl($)f [1,2,3,4]'不是那麼你需要找到某種方式區分'[1,2,3]'和'[1,2,3,4]'類型。這在普通列表中不會發生,並且[一旦你這樣做了,你可以編寫你想要的函數。](http://hackage.haskell.org/package/fixed-vector) –

+0

我相信這個問題更具體比一般的Lisp適用。 –

回答

6

類型看起來像

foldl :: (a -> b -> a) -> a -> [b] -> a 

($) :: (x -> y) -> x -> y 

申請foldl($)需要匹配(技術上,統一)的第一個參數來foldl($)類型的類型。也就是說,求解方程

a -> b -> a = (x -> y) -> x -> y 

這直接導致

a = x -> y 
b = x 
a = y 

代入第二和第三方程式進入第一:

a = b -> a 

的問題是,哈斯克爾沒有類型解決這個方程。特別是,不可能用有限數量的符號寫下解決方案!它首先擴展到

a = b -> b -> a 

然後

a = b -> b -> b -> a 

和永遠。所以有沒辦法選擇類型變量的類型,使他們匹配,GHC會抱怨大聲。

3

一般來說,你不能做你想做的事情,因爲類型系統區分具有不同數量參數的函數。本質上,你試圖做的是將一個值列表轉換爲一個函數的參數列表,這在上下文中是沒有意義的。

但是,您指向的實例實際上只是foldl (*)。如果你對一個函數中的所有變量執行相同的操作,你可以使用這個(你應該使用foldl'foldr,但你明白了)。