4import Control.Applicative (Alternative (..), liftA2)
5import Control.Monad (ap)
9data Maybe a = Nothing | Just a deriving (Functor)
11instance Applicative Maybe where
15 (<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b
18instance Monad Maybe where
19 (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
21 Nothing >>= _ = Nothing
23-- return x >>= f = f x
25-- (m >>= f) >>= g = m >>= (\x -> f x >>= g)
29safeDiv :: (Fractional a, Eq a) => a -> a -> Maybe a
32 | otherwise = Just (x / y)
36data Either e a = Left e | Right a deriving (Functor)
42 Left err >>= f = Left err
46__Exercise__: either with accumulating errors
49withOracle1 :: e -> a -> b
50withOracle2 :: e -> c -> d
52unified :: e -> (b -> c) -> a -> d
53unified ext f x = withOracle2 ext (f (withOracle1 ext x))
57instance Functor (e ->) where
60instance Applicative (e ->) where
66instance Monad (e ->) where
67 (>>=) :: (e -> a) -> (a -> e -> b) -> e -> b
68 (>>=) f g ext = g (f ext) ext
72newtype Writer w a = Writer { runWriter :: (a, w) }
74instance Functor (Writer w) where
75 fmap :: (a -> b) -> Writer w a -> Writer w b
76 fmap f = Writer . (\(x, w) -> (f x, w)) . runWriter
78instance Monoid w => Applicative (Writer w) where
79 pure :: a -> Writer w a
80 pure = Writer . (\x -> (x, mempty))
82 (<*>) :: Writer w (a -> b) -> Writer w a -> Writer w b
85instance Monoid w => Monad (Writer w) where
86 (>>=) :: Writer w a -> (a -> Writer w b) -> Writer w b
88 let Writer (y, w') = f x
89 in Writer (y, w <> w')
93newtype State s a = State { runState :: s -> (a, s) }
96instance Applicative (State s) where
97 pure :: a -> State s a
98 pure x = State $ \s -> (x, s)
102instance Monad (State s) where
103 (>>=) :: State s a -> (a -> State s b) -> State s b
104 State x >>= f = State $ \s ->
113newtype ParseError = ParseError { reason :: String }
115parseInt :: String -> Either ParseError (Int, String)
117-- parseInt "hello" -- error: gibberish
118-- parseInt "123" -- ok: (123, "")
119-- parseInt "hello123" -- error: gibberish
120-- parseInt "123hello" -- ok: (123, "hello")
124newtype Parser a = Parser {
125 runParser :: String -> Either ParseError (a, String) }
128instance Applicative Parser where
129 pure x = Parser $ \s -> Right (x, s)
132instance Monad Parser where
133 (>>=) :: Parser a -> (a -> Parser b) -> Parser b
134 (>>=) = undefined -- TODO: finish instance
138parsePair :: Parser a -> Parser b -> Parser (a, b)
139parsePair = liftA2 (,)
146parseEither pb px py = do
148 if b then Left <$> px else Right <$> py
151peek = Parser $ \xs -> case xs of
152 [] -> Left $ ParseError "empty"
153 (x : xs) -> Right (x, x : xs)
156take = Parser $ \xs -> case xs of
157 [] -> Left $ ParseError "empty"
158 (x : xs) -> Right ((), xs)
161eof = Parser $ \xs -> case xs of
163 (x : xs) -> Left $ ParseError "not empty"
165takeWhile :: (Char -> Bool) -> Parser String
166takeWhile = undefined -- TODO: write this out
169What about expressions? Like $1 + (2 * 4) + 5 * 6 - 8$?
172class Applicative f => Alternative f where
173 (<|>) :: f a -> f a -> f a
174 -- (a <|> b) <|> c = a <|> (b <|> c)
176 -- unit relative to (<|>):
182instance Alternative Parser where
183 (<|>) :: Parser a -> Parser a -> Parser a
184 (<|>) = error "TODO" -- TODO: finish
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list