Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell Is there a function for creating every variation of applying a function to a list

I want to create a list of variations of applying a function to every element of a list. Here is a quick example of what I mean.

applyVar f [a, b, c]
>> [[(f a), b, c], [a, (f b), c], [a, b, (f c)]]

Essentially It applies a function to each element of a list individually and stores each possible application in an array.

I'm not too sure how to approach a problem like this without using indexes as I have heard they are not very efficient. This is assuming that the function f returns the same type as the input list.

Is there a pre-existing function to get this behavior? If not what would that function be?


1 Answers

To see if there's a pre-existing function, first figure out its type. In this case, it's (a -> a) -> [a] -> [[a]]. Searching for that type on Hoogle only returns a handful of matches, and by inspection, none of them do what you want.

To write it yourself, note that it operates on a list, and the best way to figure out how to write a function on a list is to define it inductively. This means you need to build two cases: one for an empty list, and one for a non-empty list that assumes you already know the answer for its tail:

applyVar f [] = _
applyVar f (x:xs) = _ -- use `applyVar f xs` somehow

Now we just need to fill in the two blanks. For the nil case, it's easy. For the cons case, note that the first sublist starts with f a, and the rest will all start with a. Then, note that the tails of the rest look an awful lot like the answer for the tail. From there, the pattern should become clear.

applyVar f [] = []
applyVar f (x:xs) = (f x:xs):map (x:) (applyVar f xs)

And here's a quick demo/test of it:

Prelude> applyVar (+10) [1,2,3]
[[11,2,3],[1,12,3],[1,2,13]]
like image 182
Joseph Sible-Reinstate Monica Avatar answered Oct 21 '25 13:10

Joseph Sible-Reinstate Monica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!