В Haskell хорошо известно, что примитив map
можно использовать для применения данной функции к всем элементам списка:
λ> map toUpper "abcd"
"ABCD"
λ>
При попытке для генерации всех разделов конечного набора (списка) пригодится следующий подобный примитив:
λ> sap toUpper "abcd"
["Abcd","aBcd","abCd","abcD"]
λ>
с sap
, обозначающим последовательных приложений . Сигнатура типа может быть:
sap :: (a -> a) -> [a] -> [[a]]
Например, часть разделов набора "abcd" может быть получена из разделов "bcd" путем sap'ing их с ('a' :).
λ> pbcd = [["b","c","d"],["b","cd"],["bc","d"],["c","bd"],["bcd"]]
λ>
λ> concatMap (sap ('a':)) pbcd
[["ab","c","d"],["b","ac","d"],["b","c","ad"],["ab","cd"],["b","acd"],["abc","d"],["bc","ad"],["ac","bd"],["c","abd"],["abcd"]]
λ>
и 5 отсутствующих разделов можно затем получить, добавив «a» в качестве отдельного отдельного синглтона.
Моя проблема в том, что я не смог найти такой примитив в языковые библиотеки, и что Hoogle , учитывая сигнатуру типа, не возвращает ничего интересного.
Существует ли такой примитив, как sap
, где-нибудь в языковых библиотеках Haskell ??? Или есть способ написать его настолько коротким и простым, что он даже не заслуживает того, чтобы быть отдельной функцией, поместив его ниже так называемого порога Fairbairn ?
Сноска : можно написать sap
следующим образом:
sap :: (a -> a) -> [a] -> [[a]]
sap fn ls = fst $ foldr op ([], []) ls
where op x (ll,tl) = ( ((fn x):tl) : map (x:) ll , x:tl )
По сути, вы начинаете с [[fn (last ls)]]
в качестве начального числа и затем продвигаетесь влево. Но это кажется пешеходом не просто.