I've got an effect that needs a reference to Sem r, because it includes a streaming type. And when the stream is run within the program, the result is also in a Sem r. But r needs to include the effect itself, which includes r, so I have infinite recursion. So instead I have been putting Sem r1 inside the streaming type, where r1 is assumed to be a subset of r, just not including my r-referencing effect. But now I can't run my stream inside the program, because it runs in Sem r1, and the program runs in Sem r. To get around this, I have:
prog::(Members'[ {- most effects in here -} ]r1,r~(MyStreamingEffect(Semr1)':r1))=>foo->bar->Semr()progfoobar=do...result<-raise$useMyStreamingEffectfoobar...
This is working for now, but I don't like that I have to use raise, and that MyStreamingEffect has to be on top of the stack. What I think might be better is a function a bit like a generalised raise, with a type like SubsetOf r1 r => Sem r1 a -> Sem r a. Is this possible? Does it already exist in some form?
Well, I have a Codec effect, much like the Boomerang effect I describe here: https://funprog.zulipchat.com/#narrow/stream/216942-Polysemy/topic/Bundle.20example/near/197125529
I use this to decode a ByteString from a file into a stream of data, containing a SourceT (Sem r1) (HashMap FieldName Text), and then to re-encode this after manipulation. So the effect type is Codec ByteString (SourceT (Sem r1) (HashMap FieldName Text). Then I have a function that runs over the data in the stream, compiling a summary, with a type like Member (Error SomeError) r => SourceT (Sem r) (HashMap FieldName Text) -> Sem r Summary. I'll rewrite my above example with slightly less pseudocode:
Not sure if there's better way of doing this with current interface - maybe we could have a typeclass that encodes subset relation between rows to make this at least a little bit nicer. Or maybe you could take transformer separately as an argument of Codec, to be provided with m inside
I've got an effect that needs a reference to
Sem r
, because it includes a streaming type. And when the stream is run within the program, the result is also in aSem r
. Butr
needs to include the effect itself, which includesr
, so I have infinite recursion. So instead I have been puttingSem r1
inside the streaming type, wherer1
is assumed to be a subset ofr
, just not including myr
-referencing effect. But now I can't run my stream inside the program, because it runs inSem r1
, and the program runs inSem r
. To get around this, I have:This is working for now, but I don't like that I have to use
raise
, and thatMyStreamingEffect
has to be on top of the stack. What I think might be better is a function a bit like a generalisedraise
, with a type likeSubsetOf r1 r => Sem r1 a -> Sem r a
. Is this possible? Does it already exist in some form?How do you use it? Because normally that's what
m
indata SomeEffect m a
is forWell, I have a
Codec
effect, much like theBoomerang
effect I describe here: https://funprog.zulipchat.com/#narrow/stream/216942-Polysemy/topic/Bundle.20example/near/197125529I use this to decode a ByteString from a file into a stream of data, containing a
SourceT (Sem r1) (HashMap FieldName Text)
, and then to re-encode this after manipulation. So the effect type isCodec ByteString (SourceT (Sem r1) (HashMap FieldName Text)
. Then I have a function that runs over the data in the stream, compiling a summary, with a type likeMember (Error SomeError) r => SourceT (Sem r) (HashMap FieldName Text) -> Sem r Summary
. I'll rewrite my above example with slightly less pseudocode:This is where SourceT comes from: https://hackage.haskell.org/package/machines-0.7/docs/Data-Machine-Source.html#t:SourceT
And within
compileSummary
I call https://hackage.haskell.org/package/machines-0.7/docs/Data-Machine-Runner.html#v:foldMapT, which is what forces theSem r
in the return to be the sameSem r
as in theSourceT
.Not sure if there's better way of doing this with current interface - maybe we could have a typeclass that encodes subset relation between rows to make this at least a little bit nicer. Or maybe you could take transformer separately as an argument of
Codec
, to be provided withm
inside