>>47
tl;dr: use liftM2
liftM :: Monad m => (a -> b) -> (m a -> m b)
elem :: (a -> ([a] -> Bool))
liftM elem :: Monad m => m a -> m ([a] -> Bool)
liftM elem (Just 'd') :: Monad m => Maybe ([a] -> Bool)
Can you see why that doesn't work? You can't apply that to
Just "dongz", because it's not a function: it is a nomad with the function in his pocket. What you really want is
liftM2:
liftM2 :: Monad m => (a -> b -> c) -> (m a -> m b -> m c)
liftM2 elem :: Monad m => m a -> m [a] -> m Bool
liftM2 elem (Just 'd') (Just "dongz") :: Maybe Bool
But I won't stop here, because there's another interesting way, namely the
Applicative type class. I recommend the the
Typeclassopedia¹ for understanding this and its relationship to the others, but here's an introduction.
class Functor f => Applicative f where
pure :: a -> f a -- For a monad, pure = return
-- This is why it is called an applicative functor.
--
-- For any monad, you can define <*> as such:
-- f <*> x = liftM2 ($) f x
--
-- There are applicatives which are not monads, such as the ZipList
-- applicative (as far as I know).
--
-- E.g. in the Maybe monad this is
-- Maybe (a -> b) -> (Maybe a -> Maybe b)
(<*>) :: f (a -> b) -> (f a -> f b)
-- This is already defined in Control.Applicative.
instance Applicative Maybe where
pure = Just
Just f <*> Just x = Just (f x)
_ <*> _ = Nothing
-- Just succ <*> Just 3 = Just 4
-- [succ, (*2)] <*> [7,8] = [8,9,14,16]
-- (zip <*> tail) [1..10] = [(1,2),(2,3),(3,4),(4,5),(5,6),(6,7),(7,8),(8,9),(9,10)]
liftM elem :: Monad m => m a -> m ([a] -> Bool)
liftM elem (Just 'd') :: Maybe ([a] -> Bool)
(<*>) liftM elem (Just 'd') :: Maybe [a] -> Maybe Bool
liftM elem (Just 'd') <*> Just "dongz" :: Maybe Bool
Now, if you define
<$> = liftM², you get a nice result:
elem <$> (Just 'd') <*> Just "dongz" :: Maybe Bool
Alternative, but equivalent answers:
pure elem <*> (Just 'd') <*> Just "dongz" :: Maybe Bool
elem `liftM` (Just 'd') `ap` Just "dongz" :: Maybe Bool
¹
http://haskell.org/sitewiki/images/8/85/TMR-Issue13.pdf
² Or
<$> = fmap, it's the same since
liftM = fmap.