Подскажите Монаду в 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,

Другие вопросы по тегам