[英]Haskell Is there a function for creating every variation of applying a function to a list
我想創建一個將 function 應用於列表的每個元素的變體列表。 這是我的意思的一個簡單示例。
applyVar f [a, b, c]
>> [[(f a), b, c], [a, (f b), c], [a, b, (f c)]]
本質上,它將 function 單獨應用於列表的每個元素,並將每個可能的應用程序存儲在一個數組中。
我不太確定如何在不使用索引的情況下解決這樣的問題,因為我聽說它們效率不高。 這是假設 function f 返回與輸入列表相同的類型。
是否有預先存在的 function 來獲得這種行為? 如果不是,那 function 會是什么?
要查看是否存在預先存在的 function,首先要弄清楚它的類型。 在這種情況下,它是(a -> a) -> [a] -> [[a]]
。 在 Hoogle 上搜索該類型只會返回少數匹配項,並且通過檢查,它們都沒有滿足您的要求。
要自己編寫,請注意它對列表進行操作,並且弄清楚如何在列表上編寫 function 的最佳方法是歸納定義它。 這意味着您需要構建兩種情況:一種用於空列表,另一種用於假設您已經知道其尾部答案的非空列表:
applyVar f [] = _
applyVar f (x:xs) = _ -- use `applyVar f xs` somehow
現在我們只需要填寫兩個空白。 對於 nil 的情況,這很容易。 對於 cons 情況,請注意第一個子列表以fa
開頭,而 rest 將全部以a
開頭。 然后,請注意 rest 的尾部看起來非常像尾部的答案。 從那里,模式應該變得清晰。
applyVar f [] = []
applyVar f (x:xs) = (f x:xs):map (x:) (applyVar f xs)
這是一個快速演示/測試:
Prelude> applyVar (+10) [1,2,3]
[[11,2,3],[1,12,3],[1,2,13]]
請注意,通常情況下, lens
包含一些工具,這些工具將其作為一些更抽象工具的特例。
$ cabal repl -b lens,adjunctions
Resolving dependencies...
GHCi, version 8.10.3: https://www.haskell.org/ghc/ :? for help
> import Control.Lens
> import Control.Comonad.Representable.Store
> let updateEach f = map (peeks f) . holesOf traverse
> :t updateEach
updateEach :: Traversable t => (s -> s) -> t s -> [t s]
> updateEach negate [1..3]
[[-1,2,3],[1,-2,3],[1,2,-3]]
> import qualified Data.Map as M
> updateEach (*3) (M.fromList [('a', 1), ('b', 2), ('c', 4)])
[fromList [('a',3),('b',2),('c',4)],fromList [('a',1),('b',6),('c',4)],fromList [('a',1),('b',2),('c',12)]]
老實說,這有點矯枉過正,除非你開始需要一些lens
變得更加構圖的方式,比如:
> let updateEachOf l f = map (peeks f) . holesOf l
> updateEachOf (traverse . filtered even) negate [1..5]
[[1,-2,3,4,5],[1,2,3,-4,5]]
> updateEachOf (traverse . ix 2) negate [[1,2],[3,4,5],[6,7,8,9],[10]]
[[[1,2],[3,4,-5],[6,7,8,9],[10]],[[1,2],[3,4,5],[6,7,-8,9],[10]]]
但是,無論您最終是否需要它,知道這些工具的存在都很棒。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.