2012-01-26 5 views
2

私はMonadトランスフォーマーで初めてプレーしています。これはシンプルなハックスタックアプリです。ReaderTを使用してHappstackのServerPartレスポンスを変換する方法は?

{-# LANGUAGE OverloadedStrings #-} 

import Happstack.Lite 
import qualified Data.ByteString.Lazy.Char8 as L 

main :: IO() 
main = do 
    serve Nothing hello 

hello :: ServerPart Response 
hello = do 
    ok $ toResponse ("Hello" :: L.ByteString) 

私はそれがReaderTを使用して、いくつかのグローバル設定データを読み取ることができるようにハローを変更できるようにしたいと思います。ちょうど設定はどのように私はそれがaskを使用することができますハロー変更できます

type NewMonad = ReaderT L.ByteString (ServerPartT IO) 
runNewMonad :: NewMonad a -> L.ByteString -> ServerPart a 
runNewMonad k c = runReaderT k c 

それをシンプルに保つために、文字列であるとしましょうか?どのような種類があるのか​​分かりません。 okServerPart Responseを返すので、NewMonad Responseは正しくありません。

serveが機能するようにメインを変更するにはどうすればよいですか? ServerPart Responseが必要です。

答えて

5

実際、NewMonad Responsehelloの正しいタイプです。 liftを使用して、基礎となるモナドのアクションをトランスのモナドに変換するだけです。たとえば:あなたはモナドアクションを持っている場合

hello :: NewMonad Response 
hello = do 
    foo <- ask 
    lift . ok $ toResponse foo 
一般に

lift :: (MonadTrans t, Monad m) => m a -> t m a 

はつまり、あなたはそのモナドの上に任意のモナド変換子での行動にそれを回します。これはモナド変圧器の定義です:それはどのモナドにも変換でき、そのモナドの動作を埋め込むことができます。

:happstack-LITEが01​​を持っているフルHappstack、に比べて使用し簡素化の一つである - というよりも型クラスを使用して、任意の適切なモナドで動作するように -

1つの特定のモナドにすべてのモナドのアクションを制限すると思われます

ok :: (FilterMonad Response m) => a -> m a 

このタイプでは、標準トランスの適切なインスタンスが宣言されていると仮定するとokをそのままMyMonadに使用できます。 mainについては

、あなたがserveに渡すことができAA ServerPart Responseをリードし、ReaderT層を排除する必要があります。

main :: IO() 
main = do 
    serve Nothing $ runNewMonad hello ("Hello" :: L.ByteString) 

あなたが望んだ状態を運ぶモナドを使用していた場合(これが問題を引き起こしますserveのタイプがこのような状態のスレッドをサポートするにはあまりにも制限的であるため(IORefなどで手動でエンコードすることなく)、多くのリクエストの過程で変更されます;可能であれば、制限されていないHappstackはこれを行うことができます。とにかく非常に脆い、あなたが本当に注文に依存してはならないので、要求はそれ。)

+1

ありがとう! 2番目の方法を試してみます。このエラーが発生しました: 'ok ' –

+1

' liftの使用に起因する(Happstack.Server.Internal.Monads.FilterMonadレスポンス(ReaderT L.ByteString(ServerPartT IO))) のインスタンスがありません。 「OK」はうまくいくが、「ok」だけではない。 –

+0

happstack-server 6.5.3のドキュメント['FilterMonad'インスタンスのリスト](http://hackage.haskell.org/packages/archive/happstack-server/6.5.3/doc/html/Happstack-Server-Internal-Monads) .html#t:FilterMonad);おそらくあなたは古いバージョンを使用していますか?インスタンスは4日前に追加されたようです(http://happstack.blogspot.com/2012/01/ann-happstack-server-651.html)。 – ehird

関連する問題