I have a program like bellow.
incVal :: Num a => a -> a
incVal x = x 1
incVal' :: (Monad m, Num a) => a -> m a
incVal' x = return (x 1)
incVal'' :: (Monad m, Num a) => a -> a -> m a
incVal'' x y = return (x y)
incVal''' :: (Monad m, Num a) => a -> a -> a -> m a
incVal''' x y z = return (x y z)
main = do
print(Just 9 >>= incVal')
I can Invoke incVal'
with >>=
(as shown in the above code). But I am not understanding how to invoke incVal''
and incVal'''
with >>=
.
CodePudding user response:
You can use Applicative in combination with join
.
First, you can apply the function to the args using <$>
and <*>
:
print (incVal'' <$> Just 5 <*> Just 37)
But this is not quite enough, because the result of this will be Maybe (Maybe Int)
, due to how <*>
works, so the line above would print "Just (Just 42)"
.
So as a last step, to "unnest" the value, you can use the join
function, which is a standard Monad operation:
print (join (incVal'' <$> Just 5 <*> Just 37))
And, of course, the same approach works for incVal'''
:
print (join (incVal''' <$> Just 1 <*> Just 4 <*> Just 37))
Incidentally, even incVal'
call can be expressed in the same terms, because a combination of <$>
(aka fmap
) and join
is equivalent to >>=
:
print (join (incVal' <$> Just 42))