Advertisement
Guest User

Untitled

a guest
Jun 4th, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-# LANGUAGE FlexibleInstances      #-}
  2. {-# LANGUAGE FunctionalDependencies #-}
  3. {-# LANGUAGE MultiParamTypeClasses  #-}
  4. {-# LANGUAGE RankNTypes             #-}
  5. {-# LANGUAGE ScopedTypeVariables    #-}
  6. {-# LANGUAGE TypeFamilies           #-}
  7.  
  8. module Task2
  9.   ( MonadJS(..)
  10.   , VarJS(..)
  11.   , runSTJS
  12.   , runSTJS1
  13.   , f1
  14.   , f2
  15.   , f3
  16.   ) where
  17.  
  18. import           Control.Applicative (liftA2)
  19. import           Control.Monad       (when)
  20. import           Control.Monad.ST    (ST, runST)
  21. import           Data.Semigroup      (Semigroup, (<>))
  22. import           Data.STRef          (STRef, newSTRef, readSTRef, writeSTRef)
  23.  
  24. data Number
  25.   = Inter Int
  26.   | Frac Double
  27.   deriving (Show)
  28.  
  29. instance Semigroup Number where
  30.   Inter x <> Inter y = Inter $ x + y
  31.   Frac x <> Frac y = Frac $ x + y
  32.   Frac x <> Inter y = Frac $ x + fromIntegral y
  33.   a <> b = b <> a
  34.  
  35. instance Eq Number where
  36.   Inter x == Inter y = x == y
  37.   Frac x == Frac y = x == y
  38.   Inter x == Frac y = fromIntegral x == y
  39.   x == y = y == x
  40.  
  41. instance Ord Number where
  42.   Inter x <= Inter y = x <= y
  43.   Frac x <= Frac y = x <= y
  44.   Inter x <= Frac y = fromIntegral x <= y
  45.   Frac x <= Inter y = x <= fromIntegral y
  46.  
  47. data Val
  48.   = Boolean Bool
  49.   | Str String
  50.   | Numb Number
  51.   deriving (Show)
  52.  
  53. add :: Val -> Val -> Val
  54. add (Boolean a) (Boolean b) = Boolean $ a || b
  55. add (Str a) (Str b)         = Str $ a <> b
  56. add (Numb a) (Numb b)       = Numb $ a <> b
  57. add _ _                     = Str mempty
  58.  
  59. greater :: Val -> Val -> Bool
  60. greater (Boolean a) (Boolean b) = a > b
  61. greater (Str a) (Str b)         = a > b
  62. greater (Numb a) (Numb b)       = a > b
  63. greater _ _                     = False
  64.  
  65. class ToVal a where
  66.   toVal :: a -> Val
  67.  
  68. instance ToVal Bool where
  69.   toVal = Boolean
  70.  
  71. instance ToVal Int where
  72.   toVal = Numb . Inter
  73.  
  74. instance ToVal Double where
  75.   toVal = Numb . Frac
  76.  
  77. instance ToVal String where
  78.   toVal = Str
  79.  
  80. class Monad m =>
  81.       MonadJS m s
  82.   | m -> s
  83.   where
  84.   type Var m a :: *
  85.   newVar :: a -> m (Var m a)
  86.   writeVar :: Var m a -> a -> m ()
  87.   (@>@) :: m Val -> m Val -> m Bool
  88.   (@#) :: m () -> m a -> m a
  89.   (@+@) :: m Val -> m Val -> m Val
  90.   (@=@) :: m (Var m Val) -> m Val -> m ()
  91.   sReadVar :: m (Var m Val) -> m Val
  92.   sIf :: m Bool -> m () -> m () -> m ()
  93.   sFun1 :: (m Val -> m (Var m Val) -> m ()) -> m Val -> m Val
  94.   sWhile :: m Bool -> m () -> m ()
  95.  
  96. class VarJS a where
  97.   sWithVar :: MonadJS m s => a -> (m (Var m Val) -> m ()) -> m ()
  98.   (@=) :: MonadJS m s => m (Var m Val) -> a -> m ()
  99.  
  100. instance MonadJS (ST s) s where
  101.   type Var (ST s) a = STRef s a
  102.   newVar = newSTRef
  103.   writeVar = writeSTRef
  104.   (@>@) = liftA2 greater
  105.   (@#) = (>>)
  106.   (@+@) = liftA2 add
  107.   (@=@) mRef mX = do
  108.     x <- mX
  109.     ref <- mRef
  110.     writeSTRef ref x
  111.   sReadVar mVar = do
  112.     var <- mVar
  113.     readSTRef var
  114.   sIf cond a b = do
  115.     flag <- cond
  116.     if flag
  117.       then a
  118.       else b
  119.   sFun1 cont arg = do
  120.     resRef <- newSTRef $ Str ""
  121.     cont arg $ return resRef
  122.     readSTRef resRef
  123.   sWhile cond body = do
  124.     flag <- cond
  125.     when flag $ body >> sWhile cond body
  126.  
  127. instance VarJS Val where
  128.   sWithVar x cont = do
  129.     ref <- newVar x
  130.     cont (return ref)
  131.   (@=) mRef x = do
  132.     ref <- mRef
  133.     writeVar ref x
  134.  
  135. sWithVarGeneric ::
  136.      (MonadJS m s, ToVal a) => a -> (m (Var m Val) -> m ()) -> m ()
  137. sWithVarGeneric x = sWithVar $ toVal x
  138.  
  139. assignGeneric :: (MonadJS m s, ToVal a) => m (Var m Val) -> a -> m ()
  140. assignGeneric mRef x = mRef @= toVal x
  141.  
  142. instance VarJS Int where
  143.   sWithVar = sWithVarGeneric
  144.   (@=) = assignGeneric
  145.  
  146. instance VarJS Double where
  147.   sWithVar = sWithVarGeneric
  148.   (@=) = assignGeneric
  149.  
  150. instance VarJS Bool where
  151.   sWithVar = sWithVarGeneric
  152.   (@=) = assignGeneric
  153.  
  154. instance VarJS String where
  155.   sWithVar = sWithVarGeneric
  156.   (@=) = assignGeneric
  157.  
  158. runSTJS :: (forall s. ST s ()) -> ()
  159. runSTJS = runST
  160.  
  161. runSTJS1 :: ToVal a => a -> (forall s. ST s Val -> ST s Val) -> Val
  162. runSTJS1 x script = runST $ script (return $ toVal x)
  163.  
  164. f1 :: MonadJS m s => m Val -> m Val
  165. f1 = sFun1 $ \a res -> res @=@ a
  166.  
  167. f2 :: MonadJS m s => m ()
  168. f2 = sWithVar (toVal "keke") $ \x -> x @= toVal False
  169.  
  170. f3 :: MonadJS m s => m Val -> m Val
  171. f3 =
  172.   sFun1 $ \x res ->
  173.     sWithVar (2 :: Int) $ \y ->
  174.       sIf (sReadVar y @>@ x) (res @=@ x) (res @= toVal "Ochen zhal")
  175. -- f :: ToVal a => a -> exists b . VarJS b
  176. -- instance ToVal a => VarJS a where
  177. --   sWithVar x cont = sWithVar (toVal x) cont
  178. --   (@=) mRef x = mRef @= toVal x
  179. -- data JS s r where
  180. --   PureVal :: VarCreator a => a -> JS s Var
  181. --   JSVar :: STRef s Var -> JS s (STRef s Var)
  182. --   WithVar :: VarBox -> (JS s (STRef s Var) -> JS s ()) -> JS s ()
  183. --   (:=) :: JS s (STRef s Var) -> VarBox -> JS s ()
  184. --   (:#) :: JS s () -> JS s a -> JS s a
  185. --   (:+) :: JS s Var -> JS s Var -> JS s Var
  186. --   Fun1 :: (JS s Var -> JS s (STRef s Var) -> JS s ()) -> JS s Var -> JS s Var
  187. --   ReadVar :: JS s (STRef s Var) -> JS s Var
  188. --   (:>) :: JS s Var -> JS s Var -> JS s Bool
  189. --   If :: JS s Bool -> JS s () -> JS s () -> JS s ()
  190. --   (:<=>) :: JS s (STRef s Var) -> Var -> JS s ()
  191. -- jsToST :: forall s r . JS s r -> ST s r
  192. -- jsToST (JSVar x) = pure x
  193. -- jsToST (WithVar (VB initVal) comp) = do
  194. --   var <- newSTRef $ mkVar initVal
  195. --   jsToST $ comp $ JSVar var
  196. -- jsToST (t := (VB x)) = do
  197. --   ref <- jsToST t
  198. --   writeSTRef ref $ mkVar x
  199. -- jsToST (a :# b) = jsToST a >> jsToST b
  200. -- jsToST (a :+ b) = do
  201. --   x <- jsToST a
  202. --   y <- jsToST b
  203. --   return $ add x y
  204. -- jsToST (Fun1 comp arg) = do
  205. --   resRef <- newSTRef $ Str ""
  206. --   let jsFunc = comp arg $ JSVar resRef
  207. --   jsToST jsFunc
  208. --   readSTRef resRef
  209. -- jsToST (ReadVar var) = do
  210. --   ref <- jsToST var
  211. --   readSTRef ref
  212. -- jsToST (a :> b) = do
  213. --   x <- jsToST a
  214. --   y <- jsToST b
  215. --   return $ greater x y
  216. -- jsToST (If cond a b) = do
  217. --   flag <- jsToST cond
  218. --   if flag
  219. --     then jsToST a
  220. --     else jsToST b
  221. -- jsToST (PureVal x) = return $ mkVar x
  222. -- jsToST (t :<=> x) = do
  223. --   ref <- jsToST t
  224. --   writeSTRef ref x
  225. -- run :: (forall s . JS s ()) -> ()
  226. -- run script = runST $ jsToST script
  227. -- run1 :: VarCreator a => a -> (forall s . JS s Var -> JS s Var) -> Var
  228. -- run1 a script = runST $ jsToST $ script (PureVal a)
  229. -- f1 = Fun1 $ \a res -> res := (VB (2 :: Int))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement