Advertisement
Guest User

Untitled

a guest
Jul 26th, 2016
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.10 KB | None | 0 0
  1. {-# LANGUAGE KindSignatures #-}
  2. {-# LANGUAGE DataKinds #-}
  3. {-# LANGUAGE GADTs #-}
  4. {-# LANGUAGE ExistentialQuantification #-}
  5. {-# LANGUAGE TypeFamilies #-}
  6. {-# LANGUAGE TypeOperators #-}
  7. {-# LANGUAGE UndecidableInstances #-}
  8. {-# LANGUAGE PolyKinds #-}
  9.  
  10. module ImperativeDSL where
  11.  
  12. import GHC.TypeLits
  13.  
  14. type family HasSymbol (g :: [(Symbol,*)]) (s :: Symbol) :: Maybe * where
  15. HasSymbol '[] s = 'Nothing
  16. HasSymbol ('(s, a) ': g) s = 'Just a
  17. HasSymbol ('(t, a) ': g) s = HasSymbol g s
  18.  
  19. -- Renamed Proxy types for clarity
  20. data Name (s :: Symbol) = Var
  21. data Type (a :: *) = Of
  22.  
  23. example' :: Statement '[] ('("foo", Int) ': '[])
  24. example' = Declare (Var :: Name "foo") (Of :: Type Int)
  25.  
  26. data ScopedSymbol (g :: [(Symbol,*)]) (a :: *) = forall s.
  27. (HasSymbol g s ~ 'Just a) => The (Name s)
  28.  
  29. example :: ScopedSymbol ('("foo", Int) ': '("bar", Bool) ': '[]) Bool
  30. example = The (Var :: Name "bar")
  31.  
  32. example'' :: Statement ('("foo", Int) ': '[]) ('("foo", Int) ': '[])
  33. example'' = Assign (The (Var :: Name "foo")) (EInt 1)
  34.  
  35. data Statement (g :: [(Symbol, *)]) (h :: [(Symbol,*)]) where
  36. Declare :: Name s -> Type a -> Statement g ('(s, a) ': g)
  37. Assign :: ScopedSymbol g a -> Exp g a -> Statement g g
  38.  
  39. infixr 5 :>
  40. data Statements (g :: [(Symbol, *)]) (h :: [(Symbol,*)]) where
  41. Done :: Statements g g
  42. (:>) :: Statement g h -> Statements h i -> Statements g i
  43.  
  44. data Program = forall h. Program (Statements '[] h)
  45.  
  46. increment :: ScopedSymbol g Int -> Statement g g
  47. increment v = Assign v (EAdd (EVar v) (EInt 1))
  48.  
  49. program :: Program
  50. program = Program
  51. $ Declare (Var :: Name "foo") (Of :: Type Int)
  52. :> Assign (The (Var :: Name "foo")) (EInt 1)
  53. :> Declare (Var :: Name "bar") (Of :: Type Bool)
  54. :> increment (The (Var :: Name "foo"))
  55. :> Assign (The (Var :: Name "bar")) (ENot $ EBool True)
  56. :> Done
  57.  
  58. data Exp (g :: [(Symbol,*)]) (t :: *) where
  59. EVar :: ScopedSymbol g a -> Exp g a
  60. EBool :: Bool -> Exp g Bool
  61. EInt :: Int -> Exp g Int
  62. EAdd :: Exp g Int -> Exp g Int -> Exp g Int
  63. ENot :: Exp g Bool -> Exp g Bool
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement