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

最佳答案

我将逐步介绍它^^


问题是get使用Affjax monad,而runAff期望使用Aff monad。

Affjax定义为:

type Affjax e a = Aff (ajax :: AJAX | e) (AffjaxResponse a)


Affjax是类型的同义词。这意味着Affjax不是它自己的Monad,而是Aff Monad的特例。接下来让我们看一下:


Aff定义为:

foreign import data Aff :: # ! -> * -> *


因此,Aff是一个类型构造函数,它使用2个Types作为参数来产生一个新类型。第一个参数的种类是#!告诉我们:


#->连续...
! -> ...由效果组成


因此,当您查看Affjax类型同义词的定义时,您会看到Aff类型构造函数的第一个参数是一行效果,其中包含ajax :: Ajax效果,但对扩展名| e开放。

Aff的第二个参数只是一个类型,在Affjax的情况下,由类型变量a参数化的AffjaxResponse。

查看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" )

08-27 05:52