Подскажите Монаду в Purescript
Я работаю через определение Prompt
И его Bind
Пример описан здесь и пытается выяснить, как это будет выглядеть в Purescript.
я использую Purescript.Exists
для экзистенциального типа. Мое определение тогда:
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 = ???
Я застрял на написании Ask
дело в Bind
экземпляр и, в частности, я очень смущен типами при работе с runExists
,
Как мне написать этот экземпляр?
Спасибо,
Майкл
1 ответ
Решение
Нечто подобное должно сработать:
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)
mapPA
функция удобна для обновления PromptAskF
продолжение без необходимости многократно runExists
/ mkExists
,