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