Expose liftT - Polysemy

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Georgi Lyubenov // googleson78

Should liftT be exposed "officially"? I found it useful here:

data Authorise user m a where
  Authorise :: user -> m a -> m a -> Authorise user m a

makeSem ''Authorise

runAuthoriseSem
  :: (user -> Sem r Bool) -> Sem (Authorise user ': r) a -> Sem r a
runAuthoriseSem auth = interpretH \case
  Authorise user f err -> do
    b <- liftT $ auth user
    g <- bindT \b' ->
      if b'
      then f
      else err

    raise $ runAuthoriseSem auth $ g b

Although to be honest I'm not sure if I'm doing something wrong (the Tactics stuff is hard to follow), but liftT (or equivalently reimplementing it) was the way I found to "inject" a Sem r from the outside into a context inside an interpretH

Georgi Lyubenov // googleson78

Also the docs on it seem weird to me (I'm definitely missing something here):
Internal function to create first-order interpreter combinators out of higher-order ones.
Which one is the "first-order interpreter", and which one is the "higher-order one"?

TheMatten

@Georgi Lyubenov // googleson78 First-order one is defined in terms of interpret, higher-order in terms of interpretH
I guess liftT is fine here - maybe @Love Waern (King of the Homeless) can point out something interesting

Love Waern (King of the Homeless)

WithTactics e f m r = Tactics f m (e ': r) ': r, so you can use raise to transform Sem r a to Sem (WithTactics e f m r) a.

TheMatten

Oh - we should at least put it into docs, because that's easy to miss :big_smile:

Georgi Lyubenov // googleson78

What does the pureT in liftT do? I originally went with liftT instead of raise, because I assumed there was some reason to be doing the pureT?