-- 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