簡體   English   中英

Haskell-接受函數列表的函數

[英]Haskell- function that accepts a list of functions

我需要編寫一個函數來接受函數列表和一個值作為參數。 必須依次對值中的每個函數應用。

例如,如果我的函數被稱為compFuncs ...

compFuncs [f,g,h] val等價於f(g(h val))

我已經可以說使用foldr在這里很有用,我可以把它. 函數列表中每個函數之間的運算符,然后將其應用於val 但是,我無法完成它,這是我的嘗試......

compFuncs :: [(a->a->a)] -> a -> a
compFuncs [] val = val
compFuncs (x:xs) val = foldr //Im lost here

有人可以幫我嗎?

(我相信你打算把類型寫成composeFuncs :: [a -> a] -> a -> a因為它是這樣使用的。)

foldr通過使用您指定的替換替換列表的構造函數來工作。 例如, foldr (+) 0 [1,2,3]通過獲取列表[1,2,3] ,它實際構造為1:2:3:[] ,並用(+)替換(:) (+)[] 0如下:

1 : 2 : 3 : []
1 + 2 + 3 + 0

如果你考慮一個函數列表[f,g,h]你想要將某些值應用為\\x -> f (g (hx)) ,我們可以通過查找(:)替換來找到一個foldr [] 首先,讓我們使用組合:

\x -> f (g (h x))
= (definition of (.))
\x -> (f . g . h) x
= (eta reduction)
f . g . h

這很接近,但我們必須對空列表構造函數執行某些操作。 我們需要用某種“無所事事”或“空”功能來代替它。 幸運的是,我們有id ,保證不會以任何方式改變結果:

f . g . h
= (definition of id)
f . g . h . id

現在我們可以看到折疊:

f . g . h . id
f : g : h : []

我們把它寫成:

composeFuncs :: [a -> a] -> a -> a
composeFuncs = foldr (.) id

順便說一句,可以像這樣折疊的類型和一個充當“身份”的元素被稱為monoids *,而a -> aEndo monoid。

*還有一個額外的要求,即用於組合值的函數,如Endo (.)Sum (+) ,是關聯的。 你會注意到這使我能夠在不需要括號的情況下展示它們。

編輯

對於發現此功能的另一種方法,讓我們使用GHC 7.8的新型孔特征。 首先,我們從具有一些漏洞的composeFuncs的定義開始:

composeFuncs :: [a -> a] -> a -> a
composeFuncs = foldr _f _z

當GHC類型檢查時,我們得到一個類型錯誤,我將減少到相關的行:

tmp.hs:6:22: Found hole ‘_f’ with type: (a -> a) -> (a -> a) -> a -> a …
tmp.hs:6:25: Found hole ‘_z’ with type: a -> a …

_z開始,只有一個可能的函數類型為a -> a ,而且是id 對於_f ,我們需要一個結合兩個函數的函數來提供一個新函數。 那當然是(.) ,所以我們寫道:

composeFuncs :: [a -> a] -> a -> a
composeFuncs = foldr (.) id

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM