我如何编写一个纯脚本效果处理程序来从集合中减去效果
How can I write a purescript effect handler that subracts an effect from the set
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
部分。如何编写这样的处理程序?
尝试 pattern-match,如下所示,当然会导致错误 unexpected |
。
handleAffjax :: Affjax e a -> Aff e a
handleAffjax (Aff ( | eff1 ) resp1) = Aff eff1 resp1
谢谢大家
更新
受到下面 的回答的启发,我能够找到我的代码中的大部分问题。
我认为标题中的问题的答案是不从集合中减去一个效果,并且描述有点混乱。处理后效果依然存在
我缺少的直觉是我必须将预期的效果添加到调用函数类型中。 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
我一步步来^^
The problem is that get uses the Affjax monad, whereas runAff expects something using the Aff monad.
Affjax is defined as:
type Affjax e a = Aff (ajax :: AJAX | e) (AffjaxResponse a)
Affjax 是一个类型的同义词。这意味着 Affjax 不是它自己的 Monad,而是 Aff Monad 的特例。接下来我们一起看看:
Aff is defined as:
foreign import data Aff :: # ! -> * -> *
所以 Aff 是一个类型构造函数,它以 2 种类型作为参数 来产生一个新类型。第一个参数的 kind 是 # !这告诉我们:
- # -> 是一行...
- ! -> ... 由效果组成
因此,当您查看 Affjax 类型同义词的定义时,您可以看到 Aff 类型构造函数的第一个参数是一行效果,其中包含 ajax :: Ajax
效果但可以扩展 | e
.
Aff 的第二个参数只是一个类型,在 Affjax 的情况下,AffjaxResponse 由类型变量 a 参数化。
查看 Pursuit 表明 AffjaxResponse 只是记录的类型同义词,因此您可以使用点运算符访问它的成员。
我整理了一个最小的编译示例,可以帮助您入门:
module Main where
import Debug.Trace
import Network.HTTP.Affjax
import Control.Monad.Aff
import Control.Monad.Eff
import Control.Monad.Eff.Exception
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 = runAff errorHandler successHandler (get "http://www.myApi.com/api" )
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
部分。如何编写这样的处理程序?
尝试 pattern-match,如下所示,当然会导致错误 unexpected |
。
handleAffjax :: Affjax e a -> Aff e a
handleAffjax (Aff ( | eff1 ) resp1) = Aff eff1 resp1
谢谢大家
更新
受到下面
我认为标题中的问题的答案是不从集合中减去一个效果,并且描述有点混乱。处理后效果依然存在
我缺少的直觉是我必须将预期的效果添加到调用函数类型中。 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
我一步步来^^
The problem is that get uses the Affjax monad, whereas runAff expects something using the Aff monad.
Affjax is defined as:
type Affjax e a = Aff (ajax :: AJAX | e) (AffjaxResponse a)
Affjax 是一个类型的同义词。这意味着 Affjax 不是它自己的 Monad,而是 Aff Monad 的特例。接下来我们一起看看:
Aff is defined as:
foreign import data Aff :: # ! -> * -> *
所以 Aff 是一个类型构造函数,它以 2 种类型作为参数 来产生一个新类型。第一个参数的 kind 是 # !这告诉我们:
- # -> 是一行...
- ! -> ... 由效果组成
因此,当您查看 Affjax 类型同义词的定义时,您可以看到 Aff 类型构造函数的第一个参数是一行效果,其中包含 ajax :: Ajax
效果但可以扩展 | e
.
Aff 的第二个参数只是一个类型,在 Affjax 的情况下,AffjaxResponse 由类型变量 a 参数化。
查看 Pursuit 表明 AffjaxResponse 只是记录的类型同义词,因此您可以使用点运算符访问它的成员。
我整理了一个最小的编译示例,可以帮助您入门:
module Main where
import Debug.Trace
import Network.HTTP.Affjax
import Control.Monad.Aff
import Control.Monad.Eff
import Control.Monad.Eff.Exception
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 = runAff errorHandler successHandler (get "http://www.myApi.com/api" )