我正在研究Prompt
及其Bind
实例所定义的here的定义,并试图弄清楚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
时,我对这些类型感到非常困惑。
我该怎么写这个实例?
谢谢,
迈克尔
答案 0 :(得分: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
。