1

アプリの種類

data App = App
    { _heist       :: Snaplet (Heist App)
    , _session     :: Snaplet SessionManager
    }

イニシャライザ

...
addRoutes [ ("/ss", companyHandler)
          , ("", heistServe)
          ]
...

ハンドラー

companyHandler :: Handler b v ()
companyHandler = method GET getter <|> method POST setter
  where
    getter = do
        value <- getFromSession "name"
        writeText $ fromMaybe "nothing" value
    setter = do
        mname <- getParam "name"
        setInSession "name" (convert mname)
        getter
    convert = T.pack . B.unpack . (fromMaybe "nothing")

持っているheistServeタイプHandler b (Heist b) ()

タイプエラー:

src/Tutorial.hs:50:52:
    Couldn't match type `v' with `SessionManager'
      `v' is a rigid type variable bound by
          the type signature for companyHandler :: Handler b v ()
          at src/Tutorial.hs:50:1
    Expected type: Handler b v ()
       Actual type: Handler b SessionManager ()
    In the second argument of `method', namely `setter'
    In the second argument of `(<|>)', namely `method POST setter'
4

2 に答える 2

3

SessionManagerハンドラーを操作する関数を使用する前に、ハンドラーのコンテキストにバインドする必要があります。これは次の方法で行われます。

withTop session $ setInSession "name" (convert mname)
-- Where session is the generated lens for your snaplet

後でセッションもコミットする場合(セッションを変更し、変数を読み取っただけではないため)、次のことを行う必要があります。

withSession . withTop session $ ...

メインアプリケーションのスナップレット初期化コードに次のコードを追加すると、セッションのコミットについてまったく心配する必要がなくなります。これは、自動的に行われるためです。

wrapHandlers withSession
于 2011-12-12T15:08:47.890 に答える
0

この問題を解決する1つの方法は、次の行を使用することです。

companyHandler = with session $ method GET getter <|> method POST setter

私が役立つと思うもう1つのことは、型署名をアプリケーションに特化することです。この場合、新しい型アノテーションは次のようになります。

companyHandler :: Handler App App ()

ほとんどの場合、複数のアプリで再利用できるジェネリックコードを作成することはないため、ここで一般性を少し失っても問題はありません。より具体的な型アノテーションを使用すると、通常、エラーメッセージを解読しやすくなります。これは、コードをコンパイルする際に非常に役立ちます。すべてのアプリ/スナップレットで一般的である必要があるコードを記述している場合でも、より具体的なタイプから始めて、それが機能するようになってから一般化すると役立つ場合があります。

dflemstrがwithSessionについて言ったことは正しいです。私は通常、setInSessionの呼び出しに配置するのではなく、すべての周りでwithSessionを一度実行することを好みますが、アプリケーションに適切なことは何でも実行する必要があります。

于 2011-12-19T17:08:12.207 に答える