如何统一这些类型?

rob*_*kuz 1 types purescript

我有来自purescript-express的以下代码(但问题更为一般).

setHandler :: forall e. Handler e
setHandler = do
    idParam   <- getRouteParam "id"
    send "Yeah! "

appSetup :: forall e. App e
appSetup = do
    get "/set/:id" setHandler
Run Code Online (Sandbox Code Playgroud)

setHandler需要具有get定义为的给定签名

> :t get
forall e r.
(RoutePattern r) => r
                    -> HandlerM ( express :: EXPRESS | e ) Unit
                    -> AppM ( express :: EXPRESS | e ) Unit
Run Code Online (Sandbox Code Playgroud)

但是现在我想在其中使用以下功能 setHandler

getPointsSet :: forall f. String -> Aff ( fs :: FS | f ) Foobar
Run Code Online (Sandbox Code Playgroud)

这将给我以下编译器错误

[1/1 TypesDoNotUnify] src/Main.purs:31:5

          v
  31      send "Yeah! "
          ^

  Could not match type

    HandlerM

  with type

    Aff

  while trying to match type HandlerM
                               ( express :: EXPRESS
                               | _2
                               )
    with type Aff
                ( fs :: FS
                | _0
                )
  while checking that expression send "Yeah! "
    has type Aff
               ( fs :: FS
               | _0
               )
               _1
  in value declaration setHandler
Run Code Online (Sandbox Code Playgroud)

我明白使用getPointsSet有效地需要setHandler成为一个Aff好但是我不能用它来连接它get.

编辑

如果我尝试liftAff按照以下答案中的建议添加a

setHandler :: forall e. Handler e
setHandler = do
    idParam   <- getRouteParam "id"
    liftAff $ getPointsSet "../some-data.csv"
    send "Yeah! "
Run Code Online (Sandbox Code Playgroud)

我收到以下错误

[1/1 NoInstanceFound] src/Main.purs:28:1
   28  setHandler :: forall e. Handler e
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   No type class instance was found for
   Control.Monad.Aff.Class.MonadAff ( fs :: FS | _0 )
                                 (HandlerM ( express :: EXPRESS | e0 ))

The instance head contains unknown type variables. Consider adding a type annotation.
in value declaration setHandler
Run Code Online (Sandbox Code Playgroud)

我需要做些什么来解决这个问题?

Мак*_*иев 5

它似乎HandlerM有实例MonadAff,所以你可以使用liftAff.像这儿:

setHandler :: forall e. Handler e
setHandler = do
  idParam   <- getRouteParam "id"
  liftAff $ getPointsSet "foo"
  send "Yeah! "
Run Code Online (Sandbox Code Playgroud)

啊,对不起,行没有统一没有额外的注释appSetupsetHandler

更新后的版本

appSetup :: forall e. App (fs :: FS|e)
appSetup =
  get "/set/:id" setHandler

setHandler :: forall e. Handler (fs :: FS|e)
setHandler = do
  idParam   <- getRouteParam "id"
  liftAff $ getPointsSet "../some-data.csv"
  send "Yeah! "
Run Code Online (Sandbox Code Playgroud)

你还需要改变main类型

main :: forall e. Eff (express :: EXPRESS, fs :: FS|e) Unit
Run Code Online (Sandbox Code Playgroud)