Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.
I'm trying to run two interpreters in one function, with a type like this:
, Input (Maybe (HashMap FieldName Text))
=> UUID -> UUID
-> Sem (Input (Maybe [Text]) ': Reader Header ': r) a
-> Sem r a
It needs to read from input of Maybe (HashMap FieldName Text), then it makes a web API call to work out how to convert this into Maybe [Text], and provide this as input for the next step. This I can do, but the tricky bit is that the web API call also gives me a Header, which I also want to make available for a downstream step. Can anyone give me any pointers for how to do this?
Maybe (HashMap FieldName Text)
Isn't it that you actually want Input (Maybe [Text], Header)?
Input (Maybe [Text], Header)
No, because I will have a stream of [Text], but only one unchanging Header, so it seems wasteful to stream the Header with the [Text].
Also, they are consumed at different points in the program.
I see - then it may be more convenient to have Reader on top and do something like:
adapt m = do
header <- _
interpret _ (runReader header m)
thanks, I'll give that a go
seems to have worked -- compiled at least!
Another question... is there an easy way to do this:
mapReader :: (b -> c) -> Sem (Reader c ': r) a -> Sem (Reader b ': r) a
It feels a lot like fmap (or contramap), except of course it isn't changing the a type.
I think reinterpretH will do the job here.
If you don't actually need the local operation of Reader you can entirely avoid the Tactical stuff that's inherent in reinterpretH by using Input instead of Reader and reinterpret instead of reinterpretH
we had some discussion/progress on this issue here but it went nowhere pretty much
Oh, interesting thought! I'm yet to successfully use any of the Tactical stuff, so avoiding it for now would be nice.
mapInput f = reinterpret \case
Input -> fmap f input
something like this?
Yes, exactly. Thanks :)
/me changes all Readers to Inputs
I can do that, and use runInputConst to effectively make Input a Reader. But what if I try the same with Writer, changing it to Output? Is there a runOutputConst equivalent? It might look like this:
runOutputOnce :: (o -> Sem r ()) -> Sem (Output o ': r) a -> Sem r a
There's runOutputSem, which has that type signature, but it runs for every value, and I only want it to run once.
Or maybe I'm misunderstanding how this works. If my program only calls output once then runOutputSem will only have one value to act on.
I don't understand what you mean by runOutputConst :/
or rather I don't understand what you want runOutputConst to do
if your program calls output once runOutputSem will only "execute" once, but what if it calls output more than once?
Yeah, I concluded that it didn't actually make sense, and what I wanted was runOutputSem.