我實作了向串列的每個串列添加一個元素一次的功能。
例子:
f :: a -> [[a]] -> [[[a]]]
f 7 [[1],[2],[3]]
[[[7,1],[2],[3]],[[1],[7,2],[3]],[[1],[2],[7,3]]]
我從這個解決方案開始:
f :: a -> [[a]] -> [[[a]]]
f e xs = ((\n -> (\(x,l)-> if x==n then e:l else l) <$> zip [1..] xs) <$> [1..length xs])
你能提供一些這個函式的更好的實作嗎?
uj5u.com熱心網友回復:
您可以使用遞回來實作這一點。作為基本情況,我們考慮一個空串列:
f _ [] = []
對于非空串列,(x:xs)我們可以使用第一項,即第一個子串列。因此,我們可以生成一個串列,其中我們在第一個子串列前面加上x元素e,然后是剩余的專案xs,(e:x) : xs第一項也是如此。對于剩余的專案,我們在串列的尾部遞回xs,并將為每個子串列添加子串列x:
f e (x:xs) = ((e:x) : xs) : map (x:) (f e xs)
所以把這些放在一起給我們:
f :: a -> [[a]] -> [[[a]]]
f _ [] = []
f e (x:xs) = ((e : x) : xs) : map (x:) (f e xs)
uj5u.com熱心網友回復:
Writesplits給出了拆分串列的所有可能方法
splits :: [a] -> [([a], [a])]
splits xs = zip (inits xs) (tails xs)
例如
> splits "abc"
[("","abc"),("a","bc"),("ab","c"),("abc","")]
并使用它撰寫一個對串列的每個元素進行操作的函式
onEach :: (a -> a) -> [a] -> [[a]]
onEach f xs = [ys f z : zs | (ys, z:zs) <- splits xs]
像這樣
> onEach toUpper "abc"
["Abc","aBc","abC"]
現在f只是
f :: a -> [[a]] -> [[[a]]]
f x = onEach (x:)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/359146.html
