Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Haskell: Accumulate a Function Over a List of Monads (Maybe)

I’m learning Haskell as a way of getting to grips with a new programming paradigm. I’m getting hung up on a specific, probably basic, issue. While I’m finding lots of documentation and other stack overflow questions, I feel like I am getting lost in the noise of other people’s examples when trying to figure out how to get this working.

Critically, I’m not Just (aha) looking to get this working, I am also looking to understand the abstraction, which hitherto I’m definitely failing to do.

Let us say we have a list of Ints

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

x = [1, 2, 5]

To get the product of these Ints, I know that I can do:

result = foldr (*) 1 x

In the case where this list instead is of Maybe Ints, I’m trying to work out how to do something like

x = [Just 1, Just 2, Just 5, Nothing]

res_from_x = <magic_fold> (*) 1 x
-- res from x is Nothing

y = [Just 2, Just 3]
res_from_y = <magic_fold> (*) 1 y
-- res from y is 6

I’m sure there is a straightforward and idiomatic abstraction to this, but I’ve not managed to figure out how to manipulate fold or use foldM to meet this end.

Any help appreciated.

>Solution :

You don’t need any magic fold, you just need a suitable operator to fold with. Note that your problem doesn’t really have anything to do with lists, you could just as well ask for

x₀ = Just 5
x₁ = Nothing
res_from_x = <magic_combo> (*) x₀ x₁
-- result is `Nothing`

y₀ = Just 2
y₁ = Just 3
res_from_y = <magic_combo> (*) y₀ y₁
-- result is `Just 6`

So you need some combinator that takes an operation Int -> Int -> Int and lifts it to an operation Maybe Int -> Maybe Int -> Maybe Int. Notice further that this combinator shouldn’t actually require the operands to have type Int or any other particular type, because only the operation should be dealing with the actual values. So the type we’re looking for seems to be

    (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c

Let’s ask Hoogle about that, and it’ll come back with

liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

…using the fact that Maybe is an instance of the Applicative class.

(Of course, the fact that liftA2 has the correct type doesn’t prove that it actually does the right thing; you should always read the documentation and run some simple tests before using something that Hoogle suggests! But, in this case the first hit on Hoogle is indeed exactly what you should use.)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading