>>=
\ x -> 2*x
>>=
Monad
number :: String -> Maybe (Integer,String) number s = case span isDigit s of ([],_) -> Nothing (ds,r) -> Just (read ds,r) addition :: String -> Maybe (Integer,String) addition s = case number s of Just (n1,'+':r) -> case number r of Just (n2,r') -> Just (n1+n2,r') _ -> Nothing _ -> Nothing multiplication :: String -> Maybe (Integer,String) multiplication s = case number s of Just (n1,'*':r) -> case number r of Just (n2,r') -> Just (n1*n2,r') _ -> Nothing _ -> Nothing calculation :: String -> Maybe (Integer,String) calculation s = case addition s of Nothing -> multiplication s result -> result
number = read <$> oneOrMore (sat isDigit) addition = (+) <$> number <* char '+' <*> number multiplication = (*) <$> number <* char '*' <*> number calculation = addition <|> multiplication
number = read <$> oneOrMore (sat isDigit) addition = (+) <$> number <* char '+' <*> number multiplication = (*) <$> number <* char '*' <*> number calculation = addition <|> multiplication
Type of effect | Function type |
---|---|
Pure function: | Input -> Output |
Extra input: | Input -> Extra -> Output |
Extra output: | Input -> (Extra,Output) |
Changing the state: | Input -> State -> (State,Output) |
IO operations: | Input -> IO Output |
Success or failure: | Input -> Maybe Output |
Many results: | Input -> [Output] |
We can factor them like this:
Type of effect | The common pattern | The difference |
---|---|---|
Pure function: | Input -> M Output | M a a |
Extra input: | Input -> M Output | M a Extra -> a |
Extra output: | Input -> M Output | M a (Extra,a) |
Changing the state: | Input -> M Output | M a State->(State,a) |
IO operations: | Input -> M Output | M a IO a |
Success or failure: | Input -> M Output | M a Maybe a |
Many results: | Input -> M Output | M a [a] |
class Functor f where fmap :: (a->b) -> f a -> f b f <$> x = fmap f x
class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a->b) -> f a -> f b
class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a->m b) -> m b (=<<) :: Monad m => (a->m b) -> m a -> m b f=<<x = x>>=f
do
>>=
do x <- m1 y <- m2 x return (x+y) | ⟹ | m1 >>= \x -> do y <- m2 x return (x+y)) | ⟹ | m1 >>= \x -> m2 x >>= \y -> return (x+y) |
<$>
rNumeric :: Gen Rank rNumeric = do n <- choose (2,10) return (Numeric n)
rNumeric = Numeric <$> choose (2,10)
number :: Parser Integer number = do ds <- oneOrMore digit return (read ds)
number = read <$> oneOrMore digit
<*>
rCard :: Gen Card rCard = do s <- rSuit r <- rRank return (Card s r)
rCard = Card <$> rSuit <*> rRand
oneOrMore :: Parser item -> Parser [item] oneOrMore item = do i <- item is <- zeroOrMore item return (i:is)
oneOrMore item = (:) <$> item <*> zeroOrMore item