1

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

setHandlergetとして定義されているように、指定された署名が必要です

> :t get
forall e r.
(RoutePattern r) => r
                    -> HandlerM ( express :: EXPRESS | e ) Unit
                    -> AppM ( express :: EXPRESS | e ) Unit

ただし、次の関数を使用したいsetHandler

getPointsSet :: forall f. String -> Aff ( fs :: FS | f ) Foobar

次のコンパイラエラーが表示されます

[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

getPointsSet効果的に使用するには setHandler も になる必要があることを理解してAffいますが、それを then に接続することはできませんget

編集

liftAff以下の回答で提案されているように追加しようとすると

setHandler :: forall e. Handler e
setHandler = do
    idParam   <- getRouteParam "id"
    liftAff $ getPointsSet "../some-data.csv"
    send "Yeah! "

次のエラーが表示されます

[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

それを解決するために私は何をする必要がありますか?

4

2 に答える 2

5

HandlerMのインスタンスがあるようMonadAffですので、使用できますliftAff。ここみたいに:

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

appSetupああ、すみません、行はandの追加の注釈なしでは統合されませんsetHandler

更新版

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! "

mainタイプも変更する必要があります

main :: forall e. Eff (express :: EXPRESS, fs :: FS|e) Unit
于 2016-03-21T20:10:05.160 に答える
1

Максимの答えを拡張するには、

あなたsetHandlerの型forall e. Handler eは と同等でHandlerM (express :: EXPRESS | e) Unit あり、 は と同等HandlerM (Request -> Response -> Eff (express :: EXPRESS | e) Unit -> Aff (express :: EXPRESS | e) Unit)です。コンストラクターから関数を取り出して引数を渡すと (一部の関数はおそらく舞台裏で行うように)、Aff (express :: EXPRESS | e) Unit)

あなたgetPointsSetはタイプを持っていますforall f. String -> Aff ( fs :: FS | f ) Foobar

したがって、基本的に私たちの問題は次のように要約できます: 型(express :: EXPRESS | e)は と統一されません。( fs :: FS | f )つまり、 から呼び出すgetPointsSetsetHandlersetHandlerString(提供した ) と、現在提供されていない"foo"効果を提供する必要があります。FSそれを提供するには、 の型シグネチャsetHandlerを変更する必要があるため、代わりにAff (express :: EXPRESS | e) Unit)を使用したいと考えていAff (express :: EXPRESS, fs :: FS | r)ます。ここで、まったく同じ分析を行う必要がmainあり、メインが提供しない効果setHandlerも必要です。同じ変更を行う必要があります。setHandlerFS

これが理にかなっていることを願っています。

于 2016-03-21T21:57:28.190 に答える