Guest User

Untitled

a guest
Dec 12th, 2017
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.10 KB | None | 0 0
  1. {-# LANGUAGE ConstraintKinds #-}
  2. {-# LANGUAGE DataKinds #-}
  3. {-# LANGUAGE DeriveDataTypeable #-}
  4. {-# LANGUAGE DeriveFunctor #-}
  5. {-# LANGUAGE FlexibleContexts #-}
  6. {-# LANGUAGE FlexibleInstances #-}
  7. {-# LANGUAGE GADTs #-}
  8. {-# LANGUAGE KindSignatures #-}
  9. {-# LANGUAGE MultiParamTypeClasses #-}
  10. {-# LANGUAGE RankNTypes #-}
  11. {-# LANGUAGE TypeFamilies #-}
  12. {-# LANGUAGE TypeOperators #-}
  13.  
  14. import Data.Functor.Identity
  15. import Data.Typeable
  16.  
  17. -- Union
  18.  
  19. infixr 1 |>
  20. data (a :: * -> *) |> b
  21.  
  22. -- class Member (t :: * -> *) r
  23. -- instance Member t (t |> r)
  24. -- instance Member t r => Member t (t' |> r)
  25.  
  26. type family t `Elem` ts :: Bool where
  27. _ `Elem` Void = False
  28. t `Elem` (t |> r) = True
  29. t `Elem` (t' |> r) = t `Elem` r
  30.  
  31. type Member t r = t `Elem` r ~ True
  32.  
  33. data Union r a where
  34. Union :: (Functor t, Typeable t) => Identity (t a) -> Union r a
  35.  
  36. instance Functor (Union r) where
  37. fmap f (Union (Identity x)) = Union (Identity (fmap f x))
  38.  
  39. inj :: (Functor t, Typeable t, Member t r) => t a -> Union r a
  40. inj = Union . Identity
  41.  
  42. prj :: (Functor t, Typeable t, Member t r) => Union r a -> Maybe (t a)
  43. prj (Union f) = runIdentity <$> gcast1 f
  44.  
  45. maybeToRight :: a -> Maybe b -> Either a b
  46. maybeToRight d Nothing = Left d
  47. maybeToRight _ (Just x) = Right x
  48.  
  49. decomp :: Typeable t => Union (t |> r) a -> Either (Union r a) (t a)
  50. decomp (Union f) = maybeToRight (Union f) (runIdentity <$> gcast1 f)
  51.  
  52.  
  53. -- Eff
  54.  
  55. data Status a r = Done a | Send (Union r (Status a r))
  56.  
  57. newtype Eff r a = Eff { runEff :: forall b. (a -> Status b r) -> Status b r }
  58.  
  59. instance Functor (Eff r) where
  60. fmap f m = Eff $ \next ->
  61. runEff m (\x -> next (f x))
  62.  
  63. instance Applicative (Eff r) where
  64. pure x = Eff $ \next -> next x
  65. mf <*> mx = Eff $ \next ->
  66. runEff mf $ \f ->
  67. runEff mx $ \x ->
  68. next (f x)
  69.  
  70. instance Monad (Eff r) where
  71. m >>= f = Eff $ \next ->
  72. runEff m $ \x ->
  73. runEff (f x) next
  74.  
  75. send :: (forall b . (a -> Status b r) -> Union r (Status b r)) -> Eff r a
  76. send f = Eff (Send . f)
  77.  
  78. handleRelay :: Typeable t
  79. => Union (t |> r) a
  80. -> (a -> Eff r b)
  81. -> (t a -> Eff r b)
  82. -> Eff r b
  83. handleRelay u f h = case decomp u of
  84. Right x -> h x
  85. Left u -> send (\next -> next <$> u) >>= f
  86.  
  87.  
  88. -- Void
  89.  
  90. data Void
  91.  
  92. run :: forall a . Eff Void a -> a
  93. run m = handle (runEff m Done)
  94. where
  95. handle (Done x) = x
  96. handle (Send _) = undefined
  97.  
  98.  
  99. -- Reader
  100.  
  101. newtype Reader e a = Reader (e -> a)
  102. deriving (Functor, Typeable)
  103.  
  104. ask :: (Typeable e, Member (Reader e) r) => Eff r e
  105. ask = send (inj . Reader)
  106.  
  107. runReader :: Typeable e => Eff (Reader e |> r) a -> e -> Eff r a
  108. runReader m e = handle (runEff m Done)
  109. where
  110. handle (Done x) = return x
  111. handle (Send u) = handleRelay u handle (\(Reader next) -> handle (next e))
  112.  
  113. testReader :: Eff (Reader Integer |> Reader Double |> Void) Double
  114. testReader = do
  115. x <- ask
  116. y <- ask
  117. pure $ fromInteger x + y
  118.  
  119. main :: IO ()
  120. main = do
  121. print $ run $ runReader (runReader testReader 10) 5.5 -- 15.5
  122. print $ run $ pure "lol"
Add Comment
Please, Sign In to add comment