


Maybe data type defines two related contexts:
 data Maybe a = Nothing | Just a Just a versus Nothing . But first, let's talk about functors!
fmap to the rescue. fmap is a guy from the street, fmap knows a lot about contexts. He knows how to apply a function to a value wrapped in a context. Let's say that you want to apply (+3) to Just 2 . Use fmap : > fmap (+3) (Just 2) Just 5 
fmap showed us how to do it! But how does he know how to properly apply a function?
fmap is applied to it. This is how fmap works:
 > fmap (+3) (Just 2) Just 5 fmap magically apply this function, because Maybe is a functor. It defines how to apply functions to Just 's and Nothing 's: instance Functor Maybe where fmap func (Just val) = Just (func val) fmap func Nothing = Nothing fmap (+3) (Just 2) :
fmap , and apply, please, (+3) to Nothing ."
 > fmap (+3) Nothing Nothing 
fmap knows what to do; you started with Nothing and finish with Nothing too! This is fmap zen. And now it is clear why the data type Maybe exists. For example, how would you work with a record in a database in a language without Maybe : post = Post.find_by_id(1) if post return post.title else return nil end  fmap (getPostTitle) (findPost 1) findPost returns a message, then we display its header using getPostTitle . If it returns Nothing , then we return Nothing ! Damn graceful, huh?<$> Is the infix version of fmap , so instead of the code above you can often find: getPostTitle <$> (findPost 1) 
 instance Functor [] where fmap = map  fmap (+3) (+1) 

 > import Control.Applicative > let foo = fmap (+3) (+2) > foo 10 15  instance Functor ((->) r) where fmap fg = f . g fmap to a function, you simply make a composition of functions!

Control.Applicative defines a <*> that knows how to apply a function wrapped in a context to a value wrapped in a context :
 Just (+3) <*> Just 2 == Just 5 <*> can lead to interesting situations. For example: > [(*2), (+3)] <*> [1, 2, 3] [2, 4, 6, 4, 5, 6] 
 > (+) <$> (Just 5) Just (+5) > Just (+5) <$> (Just 4) ???         JUST  > (+) <$> (Just 5) Just (+5) > Just (+5) <*> (Just 3) Just 8 Applicative technically pushes Functor aside. “The big guys can use functions with any number of arguments,” he says. “Armed with <$> and <*> , I can take any function that expects any number of unpacked arguments. Then I will give her all the packed values ​​and get the same packed result! BVAHAHAHAHAHAHA! " > (*) <$> Just 5 <*> Just 3 Just 15 
liftA2 function that does the same thing: > liftA2 (*) (Just 5) (Just 3) Just 15 

>>= (pronounced “binding” ( bind )), which allows to do this.Maybe - this is a monad:
half be a function that works only with even numbers: half x = if even x then Just (x `div` 2) else Nothing 

>>= to push the packed value through the function. Here's a photo >>= :
 > Just 3 >>= half Nothing > Just 4 >>= half Just 2 > Nothing >>= half Nothing Monad is another type class. Here is its partial definition: class Monad m where (>>=) :: ma -> (a -> mb) -> mb >>= :
Maybe is a monad: instance Monad Maybe where Nothing >>= func = Nothing Just val >>= func = func val Just 3 !
Nothing to the input, it is still easier:
 > Just 20 >>= half >>= half >>= half Nothing 

Maybe is Functor , Applicative and Monad in one person.IO monad:
getLine takes no arguments and gets user data from login:
 getLine :: IO String readFile takes a string (file name) and returns its contents:
 readFile :: FilePath -> IO String putStrLn takes a string and prints it:
 putStrLn :: String -> IO () >>= !
 getLine >>= readFile >>= putStrLn do notation: foo = do filename <- getLine contents <- readFile filename putStrLn contents Functor type class.Applicative type class.Monad type class.
fmap or <$><*> or liftA>>= or liftMSource: https://habr.com/ru/post/183150/
All Articles