PureScript by Example,在The Eff Monad -> Handlers and Actions一节中指出“[效果] 处理程序通常会从集合中减去效果”。但是,这些示例相当不透明,我无法弄清楚如何编写自己的处理程序来实现这一点。
具体来说,我正在使用 purescript-aff 和purescript-affjax。我想将 runAff(来自 purescript-aff)与 get(来自 purescript-affjax)结合使用。
问题是get
使用 Affjax monad,而runAff
期望使用 Aff monad。
Affjax 定义为:
type Affjax e a = Aff (ajax :: AJAX | e) (AffjaxResponse a)
Aff 定义为:
foreign import data Aff :: # ! -> * -> *
因此,我想编写一个具有以下类型的函数:
Affjax e a -> Aff e a
在我看来,这似乎需要一个处理程序来减去ajax
效果集的一部分。如何编写这样的处理程序?
尝试进行模式匹配,如下所示,当然会导致错误unexpected |
。
handleAffjax :: Affjax e a -> Aff e a
handleAffjax (Aff ( | eff1 ) resp1) = Aff eff1 resp1
谢谢大家。
更新
受@christoph-hegemann下面的回答启发,我能够找到我的代码的大部分问题。
我认为标题中问题的答案是不会从集合中减去效果,而且这种描述有点令人困惑。处理后效果仍然存在。
我缺少的直觉是我必须将预期效果添加到调用函数类型。缺少类型声明在main
某种程度上隐藏了这一点。当我将 Christoph 的示例转换为以下编译示例时,我解决了这个问题:
module Main where
import Debug.Trace
import Network.HTTP.Affjax
import Control.Monad.Aff
import Control.Monad.Eff
import Control.Monad.Eff.Exception
initialUrl :: URL
initialUrl = "http://127.0.0.1:8000/api/v1/navitem/2/"
runGet :: forall e. Eff (ajax :: AJAX, trace :: Trace | e) Unit
runGet = runAff errorHandler successHandler (get initialUrl)
errorHandler :: forall e. Error -> Eff (trace :: Trace | e) Unit
errorHandler err = print err
successHandler :: forall e. AffjaxResponse String -> Eff (trace :: Trace | e) Unit
successHandler res = print res.response
main = runGet