haskell-effectful / effectful-contrib

Libraries for the Effectful Haskell effects system
22 stars 3 forks source link

Binding for co-log #10

Open mmhat opened 3 years ago

mmhat commented 3 years ago

co-log

ambroslins commented 2 years ago

Hi, I would like to work on this issue, but I am stuck on choosing the right Monad m for the LogAction m msg.

After some trying around I came up with this:

data Log :: (Type -> Type) -> Type -> Effect

type instance DispatchOf (Log m msg) = 'Static

data instance StaticRep (Log m msg) = Log (LogAction m msg)

runLog :: LogAction (Eff es) msg -> Eff (Log (Eff es) msg ': es) a -> Eff es a
runLog = evalStaticRep . Log

logMsg :: Log (Eff es) msg :> es => msg -> Eff es ()
logMsg msg = do
  Log (LogAction action) <- getStaticRep
  action msg

However this does not work because the Log effect will always contain itself. I think for this to work a subset like typeclass is required, like this:

logMsg :: (Log (Eff logEffects) msg :> allEffects, Subset logEffects allEffects) => msg -> Eff allEffects ()

Another way i can think of is just fixing the Monad to IO (or Eff [IOE]), like:

data Log :: Type -> Effect
data instance StaticRep (Log  msg) = Log (LogAction IO msg)

I think, if the Reader effect would provide a MonadReader instance, most functions from co-log would just work with WithLog.

Basically my question is: what is the best way to move forward?

ambroslins commented 2 years ago

Looks like this will be solved soon: https://github.com/arybczak/effectful/issues/52

I will use this new class as the Subset class I proposed.

arybczak commented 2 years ago

I don't think it's going to work as you'd expect it to.

I'm not familiar with co-log, but from what I see from briefly looking at hackage docs you should carry LogAction IO msg and execute it in logMsg using unsafeEff. You also then need the runLog function to have an IOE :> es constraint for safety (it's going to be described in the documentation of static effects, which is not yet done, but basically if any of static effect operations uses unsafeEff to introduce side effects, the run function needs to require IOE).

Also the StaticRep instance should be a newtype, not a data.

ambroslins commented 2 years ago

Thanks for the feedback. You are right, this does not work as I expected, the logEffects would be ambiguous.