Guest User

Untitled

a guest
Oct 17th, 2018
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.57 KB | None | 0 0
  1. module Transformers where
  2. import Control.Monad.Identity
  3. import Control.Monad.Error
  4. import Control.Monad.Reader
  5. import Control.Monad.State
  6. import Control.Monad.Writer
  7. import Data.Maybe
  8. import qualified Data.Map as Map
  9.  
  10. type Name = String
  11. data Exp = Lit Integer
  12. | Var Name
  13. | Plus Exp Exp
  14. | Abs Name Exp
  15. | App Exp Exp
  16. deriving(Show)
  17. data Value = IntVal Integer
  18. | FunVal Env Name Exp
  19. deriving (Show)
  20.  
  21. type Env = Map.Map Name Value
  22.  
  23.  
  24. eval0 :: Env -> Exp -> Value
  25. eval0 env (Lit i) = IntVal i
  26. eval0 env (Var n) = fromJust (Map.lookup n env)
  27.  
  28. eval0 env (Plus e1 e2) = let IntVal i1 = eval0 env e1
  29. IntVal i2 = eval0 env e2
  30. in
  31. IntVal (i1 + i2)
  32. eval0 env (Abs n e) = FunVal env n e
  33. eval0 env (App e1 e2) = let val1 = eval0 env e1
  34. val2 = eval0 env e2
  35. in case val1 of
  36. FunVal env' n body -> eval0 (Map.insert n val2 env') body
  37.  
  38.  
  39. exampleExp = Lit 12 `Plus` (App (Abs "x" (Var "x")) (Lit 4 `Plus` (Lit 2)))
  40.  
  41.  
  42. type Eval1 a = Identity a
  43. runEval1 :: Eval1 a -> a
  44. runEval1 env = runIdentity env
  45.  
  46.  
  47.  
  48. eval1 :: Env -> Exp -> Eval1 Value
  49. eval1 env (Lit i) = return $ IntVal i
  50.  
  51. eval1 env (Var n) = return $ fromJust $ (Map.lookup n env)
  52.  
  53. eval1 env (Plus e1 e2) = do IntVal i1 <- eval1 env e1
  54. IntVal i2 <- eval1 env e2
  55. return $ IntVal (i1 + i2)
  56. eval1 env (Abs n e) = return $ FunVal env n e
  57.  
  58. eval1 env (App e1 e2) = do val1 <- eval1 env e1
  59. val2 <- eval1 env e2
  60. case val1 of
  61. FunVal env' n body ->
  62. eval1 (Map.insert n val2 env') body
  63.  
  64.  
  65. type Eval2 a = ErrorT String Identity a
  66.  
  67. runEval2 :: Eval2 a -> Either String a
  68. runEval2 env = runIdentity (runErrorT env)
  69.  
  70. eval2a :: Env -> Exp -> Eval2 Value
  71. eval2a env (Lit i) = return $ IntVal i
  72. eval2a env (Var n) = return $ fromJust $ Map.lookup n env
  73.  
  74. eval2a env (Plus e1 e2) = do IntVal i1 <- eval2a env e1
  75. IntVal i2 <- eval2a env e2
  76. return $ IntVal (i1 + i2)
  77. eval2a env (Abs n e) = return $ FunVal env n e
  78. eval2a env (App e1 e2) = do val1 <- eval2a env e1
  79. val2 <- eval2a env e2
  80. case val1 of
  81. FunVal env' n body ->
  82. eval2a (Map.insert n val2 env') body
  83.  
  84. eval2b :: Env -> Exp -> Eval2 Value
  85. eval2b env (Lit i) = return $ IntVal i
  86. eval2b env (Var n) = return $ fromJust $ Map.lookup n env
  87. eval2b env (Plus e1 e2) = do e1' <- eval2b env e1
  88. e2' <- eval2b env e2
  89. case (e1', e2') of
  90. (IntVal i1, IntVal i2) ->
  91. return $ IntVal (i1 + i2)
  92. _ ->
  93. throwError "type error"
  94.  
  95. eval2b env (Abs n e) = return $ FunVal env n e
  96. eval2b env (App e1 e2) = do val1 <- eval2b env e1
  97. val2 <- eval2b env e2
  98. case val1 of
  99. FunVal env' n body ->
  100. eval2b (Map.insert n val2 env') body
  101. _ -> throwError "type error"
  102.  
  103.  
  104.  
  105.  
  106. eval2c :: Env -> Exp -> Eval2 Value
  107. eval2c env (Lit i) = return $ IntVal i
  108. eval2c env (Var n) = return $ fromJust $ Map.lookup n env
  109. eval2c env (Plus e1 e2) = do IntVal i1 <- eval2c env e1
  110. IntVal i2 <- eval2c env e2
  111. return $ IntVal (i1+ i2)
  112. eval2c env (Abs n e) = return $ FunVal env n e
  113. eval2c env (App e1 e2) = do FunVal env' n body <- eval2c env e1
  114. val2 <- eval2c env e2
  115. eval2c (Map.insert n val2 env') body
  116.  
  117. eval2 :: Env -> Exp -> Eval2 Value
  118. eval2 env (Lit i) = return $ IntVal i
  119. eval2 env (Var n) = case Map.lookup n env of
  120. Nothing -> throwError ("unbound variable: " ++ n)
  121. Just val -> return val
  122. eval2 env (Plus e1 e2) = do e1' <- eval2 env e1
  123. e2' <- eval2 env e2
  124. case (e1',e2') of
  125. (IntVal i1, IntVal i2) ->
  126. return $ IntVal (i1 + i2)
  127. _ ->
  128. throwError "type error in addtional"
  129. eval2 env (Abs n e) = return $ FunVal env n e
  130. eval2 env (App e1 e2) = do val1 <- eval2 env e1
  131. val2 <- eval2 env e2
  132. case val1 of
  133. FunVal env' n body ->
  134. eval2 (Map.insert n val2 env') body
  135. _ -> throwError "type error in application"
  136.  
  137. type Eval3 a = ReaderT Env (ErrorT String Identity) a
  138.  
  139. runEval3 :: Env -> Eval3 a -> Either String a
  140. runEval3 env ev = runIdentity (runErrorT (runReaderT ev env))
  141.  
  142. eval3 :: Exp -> Eval3 Value
  143. eval3 (Lit i) = return $ IntVal i
  144. eval3 (Var n) = do env <- ask
  145. case Map.lookup n env of
  146. Nothing -> throwError ("unbound variable " ++ n)
  147. Just val -> return val
  148. eval3 (Plus e1 e2) = do e1' <- eval3 e1
  149. e2' <- eval3 e2
  150. case (e1', e2') of
  151. (IntVal i1, IntVal i2) ->
  152. return $ IntVal (i1 + i2)
  153. _ -> throwError "type error in addtional"
  154. eval3 (Abs n e) = do env <- ask
  155. return $ FunVal env n e
  156.  
  157. eval3 (App e1 e2) = do val1 <- eval3 e1
  158. val2 <- eval3 e2
  159. case val1 of
  160. FunVal env' n body ->
  161. local (const (Map.insert n val2 env'))
  162. (eval3 body)
  163. _ -> throwError "type error in application"
  164.  
  165.  
  166.  
  167.  
  168. type Eval4 a = ReaderT Env (ErrorT String (StateT Integer Identity)) a
  169.  
  170. runEval4 :: Env -> Integer -> Eval4 a -> (Either String a, Integer)
  171. runEval4 env st ev = runIdentity (runStateT (runErrorT (runReaderT ev env)) st)
  172.  
  173. tick :: (Num s, MonadState s m) => m ()
  174. tick = do st <- get
  175. put (st + 1)
  176. eval4 :: Exp -> Eval4 Value
  177. eval4 (Lit i) = do tick
  178. return $ IntVal i
  179. eval4 (Var n) = do tick
  180. env <- ask
  181. case Map.lookup n env of
  182. Nothing -> throwError ("unbound variable: " ++ n)
  183. Just val -> return val
  184. eval4 (Plus e1 e2) = do tick
  185. e1' <- eval4 e1
  186. e2' <- eval4 e2
  187. case (e1', e2') of
  188. (IntVal i1, IntVal i2) ->
  189. return $ IntVal (i1 + i2)
  190. _ -> throwError "type error in addtional "
  191. eval4 (Abs n e) = do tick
  192. env <- ask
  193. return $ FunVal env n e
  194.  
  195. eval4 (App e1 e2) = do tick
  196. val1 <- eval4 e1
  197. val2 <- eval4 e2
  198. case val1 of
  199. FunVal env' n body ->
  200. local (const (Map.insert n val2 env'))
  201. (eval4 body)
  202. _ -> throwError "type error in application"
  203.  
  204.  
  205. type Eval4' a = ReaderT Env (StateT Integer (ErrorT String Identity)) a
  206. runEval4' :: Env -> Integer -> Eval4' a -> (Either String (a, Integer))
  207. runEval4' env st ev = runIdentity (runErrorT (runStateT (runReaderT ev env) st))
  208.  
  209. type Eval5 a = ReaderT Env (ErrorT String
  210. (WriterT [String]
  211. (StateT Integer Identity))) a
  212. runEval5 :: Env -> Integer -> Eval5 a -> ((Either String a, [String]), Integer)
  213.  
  214. runEval5 env st ev =
  215. runIdentity (runStateT (runWriterT (runErrorT (runReaderT ev env))) st)
  216.  
  217. eval5 :: Exp -> Eval5 Value
  218. eval5 (Lit i) = do tick
  219. return $ IntVal i
  220. eval5 (Var n) = do tick
  221. tell [n]
  222. env <- ask
  223. case Map.lookup n env of
  224. Nothing -> throwError ("unbound variable: " ++ n)
  225. Just val -> return val
  226. eval5 (Plus e1 e2) = do tick
  227. e1' <- eval5 e1
  228. e2' <- eval5 e2
  229. case (e1', e2') of
  230. (IntVal i1, IntVal i2) ->
  231. return $ IntVal (i1 + i2)
  232. _ ->
  233. throwError ("type error in addition")
  234. eval5 (Abs n e) = do tick
  235. env <- ask
  236. return $ FunVal env n e
  237. eval5 (App e1 e2) = do tick
  238. val1 <- eval5 e1
  239. val2 <- eval5 e2
  240. case val1 of
  241. FunVal env' n body ->
  242. local (const (Map.insert n val2 env'))
  243. (eval5 body)
  244. _ -> throwError "type error in application"
  245.  
  246.  
  247.  
  248.  
  249.  
  250. type Eval6 a = ReaderT Env (ErrorT String
  251. (WriterT [String] (StateT Integer IO))) a
  252.  
  253. runEval6 :: Env -> Integer -> Eval6 a ->
  254. IO ((Either String a, [String]), Integer)
  255.  
  256. runEval6 env st ev =
  257. runStateT (runWriterT (runErrorT (runReaderT ev env))) st
  258.  
  259. eval6 :: Exp -> Eval6 Value
  260. eval6 (Lit i) = do tick
  261. liftIO $ print i
  262. return $ IntVal i
  263. eval6 (Var n) = do tick
  264. tell [n]
  265. env <- ask
  266. case Map.lookup n env of
  267. Nothing -> throwError ("unbound variable: " ++ n)
  268. Just val -> return val
  269. eval6 (Plus e1 e2) = do tick
  270. e1' <- eval6 e1
  271. e2' <- eval6 e2
  272. case (e1', e2') of
  273. (IntVal i1, IntVal i2) ->
  274. return $ IntVal (i1 + i2)
  275. _ -> throwError "type error in additon"
  276. eval6 (Abs n e) = do tick
  277. env <- ask
  278. return $ FunVal env n e
  279. eval6 (App e1 e2) = do tick
  280. val1 <- eval6 e1
  281. val2 <- eval6 e2
  282. case val1 of
  283. FunVal env' n body ->
  284. local (const (Map.insert n val2 env'))
  285. (eval6 body)
  286. _ -> throwError "type error in application"
Add Comment
Please, Sign In to add comment