I have a function like so
foo :: X -> Y -> Z
and I have two separate calculations that are done to get my variables of type X and Y, but they can fail, so I use a Maybe
calc1 :: A -> Maybe X
calc2 :: B -> Maybe Y
now I am not sure how to use the monad operations to get this desired behaviour
safe_foo :: Maybe X -> Maybe Y -> Maybe Z
safe_foo Nothing _ = Nothing
safe_foo _ Nothing = Nothing
safe_foo (Just x) (Just y) = Just (foo x y)
what is the best way to do this?
You just need liftA2, which is defined as part of the Applicative type class.
safe_foo = liftA2 foo
Or alternatively, in the "applicative style":
safe_foo mx my = foo <$> mx <*> my
                        You could use the monad with a do block
safe_foo mx my = do    -- BTW, we underscore_case is unconventional in Haskell,
   x <- mx             -- preferrably use camelCase instead
   y <- my
   return $ foo x y
...or, desugared&simplified,
safe_foo mx my = mx >>= (<$>my) . foo
but really you don't need Monad here, Applicative is enough.
safe_foo = liftA2 foo
or directly using the calc-functions,
   foo <$> calc1 a <*> calc2 b
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With