-- Most tests copied from polysemy-plugin: -- -- https://github.com/polysemy-research/polysemy/tree/master/polysemy-plugin/test -- -- (c) 2019 Sandy Maguire, licensed under BSD-3-Clause {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE OverloadedStrings #-} {-# OPTIONS_GHC -Wno-unused-foralls #-} module Main where import Data.String import Unsafe.Coerce import Effectful import Effectful.Dispatch.Dynamic import Effectful.Error.Static import Effectful.Labeled import Effectful.Labeled.Reader import Effectful.State.Static.Local main :: IO () main = pure () ---------------------------------------- -- Tests data Function i o :: Effect where Call :: i -> Function i o m o type instance DispatchOf (Function i o) = Dynamic call :: (HasCallStack, Function i o :> es) => i -> Eff es o call a = send $ Call a callTest :: ( Function Int a :> es , Function a Int :> es , Labeled "x" (Reader Int) :> es , Labeled "y" (Reader b) :> es , IsString s , Function s a :> es ) => Eff es () callTest = do a1 <- call 1 a2 <- call "" _ <- call a1 _ <- call a2 (_::Int) <- ask _ <- ask @"y" pure () class X a where xxx :: a class MPTC a b where mptc :: a -> b instance MPTC Bool Int where mptc _ = 1000 ordPut :: (State s :> es, Ord s) => s -> Eff es () ordPut = put uniquelyX :: (X a, State a :> es) => Eff es () uniquelyX = put xxx uniquelyA :: (Num a, State a :> es, State b :> es, IsString b) => Eff es () uniquelyA = put 10 >> put "" uniquelyInt :: (State Int :> es, State String :> es) => Eff es () uniquelyInt = ordPut 10 >> put "" uniquelyString :: (State Int :> es, State String :> es) => Eff es () uniquelyString = put mempty uniquelyB :: (MPTC Bool b, State String :> es, State b :> es) => Eff es () uniquelyB = put $ mptc False uniquelyState' :: (Error () :> es, State () :> es) => Eff es () uniquelyState' = pure () idState :: State s :> es => Eff es () idState = do s <- get put s intState :: State Int :> es => Eff es () intState = put 10 numState :: Num a => State a :> es => Eff es () numState = put 10 strState :: State String :> es => Eff es () strState = put "Hello" oStrState :: IsString a => State a :> es => Eff es () oStrState = put "hello" err :: Error e :> es => Eff es Bool err = catchError (throwError_ (error "")) (\_ _ -> pure True) errState :: (Num s, Error e :> es, State s :> es) => Eff es Bool errState = do numState err newtype MyString = MyString String deriving newtype (IsString, Eq, Show) data Janky = forall s. Janky (forall _i. Eff '[State s] ()) jankyState :: Janky jankyState = Janky $ put True -- The plugin disambiguates effects for concrete rows too unsafeUnjank :: Janky -> Eff '[State Bool] () unsafeUnjank (Janky m) = unsafeCoerce m data MoreJanky = forall y. MoreJanky (MPTC Bool y => Eff [State (Bool, y), State (Char, y)] ()) mptcGet :: MPTC x Bool => x mptcGet = undefined moreJankyState :: MoreJanky moreJankyState = MoreJanky $ put (mptcGet, True) data TaggedState k s :: Effect where TaggedGet :: forall k s m. TaggedState k s m s TaggedPut :: forall k s m. s -> TaggedState k s m () type instance DispatchOf (TaggedState k s) = Dynamic runTaggedState :: s -> Eff (TaggedState k s : es) a -> Eff es (a, s) runTaggedState s = reinterpret_ (runState s) $ \case TaggedGet -> get TaggedPut s' -> put s' test :: (TaggedState Char Int :> es, TaggedState Bool Int :> es) => Eff es () test = do send $ TaggedPut @Bool 10 send $ TaggedPut @Char (-10) newtype Select a = Select a data DBAction whichDb :: Effect where DoSelect :: Select a -> DBAction whichDb m (Maybe a) type instance DispatchOf (DBAction whichDb) = Dynamic runDBAction :: Eff (DBAction which : es) a -> Eff es a runDBAction = interpret_ $ \case DoSelect (Select a) -> pure $ Just a