Reputation: 1354
I'm working through the definition of Prompt
and its Bind
instance described here and was trying to figure out how this would look in Purescript.
I am using Purescript.Exists
for the existential type. My defintion is then:
data PromptAskF p r a
= PromptAskF (p a) (a -> Prompt p r)
type PromptAsk p r = Exists (PromptAskF p r)
data Prompt p r
= Ask (PromptAsk p r)
| Answer r
instance bindPrompt :: Bind (Prompt p) where
bind (Answer x) k = k x
bind (Ask ask) k = ???
I am stuck on writing the Ask
case in the Bind
instance and, in particular, I'm very confused about the types when working with runExists
.
How should I write this instance?
Thanks,
Michael
Upvotes: 2
Views: 205
Reputation: 4649
Something like this should do the trick:
data PromptAskF p r a
= PromptAskF (p a) (a -> Prompt p r)
type PromptAsk p r = Exists (PromptAskF p r)
mapPA
:: forall p r r'
. (forall a. (a -> Prompt p r) -> (a -> Prompt p r'))
-> PromptAsk p r
-> PromptAsk p r'
mapPA f = runExists \(PromptAskF req cont) -> mkExists $ PromptAskF req (f cont)
data Prompt p r
= Ask (PromptAsk p r)
| Answer r
instance functorPrompt :: Functor (Prompt p) where
map f (Answer r) = Answer (f r)
map f (Ask ask) = Ask $ mapPA (map (map f)) ask
instance applyPrompt :: Apply (Prompt p) where
apply = ap
instance applicativePrompt :: Applicative (Prompt p) where
pure = Answer
instance bindPrompt :: Bind (Prompt p) where
bind (Answer x) k = k x
bind (Ask ask) k = Ask $ mapPA (\cont ans -> cont ans >>= k) ask
instance monadPrompt :: Monad (Prompt p)
The mapPA
function is a convenience for updating the PromptAskF
continuation without having to repeatedly runExists
/ mkExists
.
Upvotes: 1