2016-03-21 6 views
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 

setHandler私は私に次のようになりますどのsetHandler

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

以内に次の関数を使用したいがgetが今

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

のように定義されたように与えられた署名を持っている必要がありますコンパイラエラー

[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になる必要がありますが、getで配線することはできません。

編集

私は

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

以下の回答で提案されているようliftAffを追加しようとすると、私は私が何をする必要がありますどのような次のエラー

[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 

を取得それを解決する?

答えて

5

HandlerMMonadAffというインスタンスがあるようですので、liftAffを使用できます。ここのように:

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

ああ、申し訳ありませんが、行は、あなたがまた

mainタイプを変更する必要があり 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! " 

の追加の注釈なしに統一していません

main :: forall e. Eff (express :: EXPRESS, fs :: FS|e) Unit 
+0

yup - それでした。ソートの;-)実際には、実際にはsetHandlerのシグネチャを持たない – robkuz

1

は、Максимの回答時に展開するには

あなた setHandler順番に HandlerM (Request -> Response -> Eff (express :: EXPRESS | e) Unit -> Aff (express :: EXPRESS | e) Unit)と同等である HandlerM (express :: EXPRESS | e) Unit と等価であるタイプ forall e. Handler eを持っています。我々は(いくつかの機能は、おそらく舞台裏ように)コンストラクタから機能を取り出し、引数を指定して、それを養うならば、我々は Aff (express :: EXPRESS | e) Unit)

に残っているあなたのgetPointsSetだから基本的に私たちの問題を軽減することができるタイプforall f. String -> Aff (fs :: FS | f) Foobar

を持っていますこれに:タイプ(express :: EXPRESS | e)(fs :: FS | f)で統一しない、これはsetHandlerからgetPointsSetを呼び出すために、setHandlerStringを供給(あなたが"foo"を供給)し、それが現在提供しない効果FSばならないことを意味します。それを供給するためには、setHandlerのタイプシグネチャが変更されなければならないので、Aff (express :: EXPRESS | e) Unit)の代わりにAff (express :: EXPRESS, fs :: FS | r)が必要です。 mainsetHandlerについても同様の解析を行う必要があります。setHandlerには、主に供給しない効果FSが必要です。同じ変更を行う必要があります。

これは意味があると思います。

関連する問題