-
Notifications
You must be signed in to change notification settings - Fork 0
/
55monadTransformers.hs
62 lines (47 loc) · 1.76 KB
/
55monadTransformers.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import Control.Monad
import Control.Applicative
import Control.Monad.Trans
import Data.Char
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
-- make ```MaybeT m``` an instance of Monad type
instance Monad m => Monad (MaybeT m) where
return = MaybeT . return. Just
-- The signature of (>>=), specialized to MaybeT m:
-- (>>=) :: MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b
x >>= f = MaybeT $ do maybeValue <- runMaybeT x
case maybeValue of
Nothing -> return Nothing
(Just val) -> runMaybeT $ f val
-- everything that is a monad should also be a functor, and an applicative
instance (Monad m) => Applicative (MaybeT m) where
pure = return
(<*>) = ap
instance (Monad m) => Functor (MaybeT m) where
fmap = liftM
-- see https://stackoverflow.com/questions/32929252/can-ghc-derive-functor-and-applicative-instances-for-a-monad-transformer
instance Monad m => Alternative (MaybeT m) where
empty = MaybeT $ return Nothing
x <|> y = MaybeT $ do maybe_value <- runMaybeT x
case maybe_value of
Nothing -> runMaybeT y
Just _ -> return maybe_value
instance Monad m => MonadPlus (MaybeT m) where
mzero = empty
mplus = (<|>)
instance MonadTrans MaybeT where
lift = MaybeT . (liftM Just)
isValid :: String -> Bool
isValid s = length s >= 8
&& any isAlpha s
&& any isNumber s
&& any isPunctuation s
test :: MaybeT IO String
test = do
x <- lift getLine
let y = x ++ "no"
return (y)
test2 :: [ Int]
test2 = do
x <- [ 10,11,12]
let k = x + 1
return k