2017-05-08 3 views
3

私は設定を読んでいる何かを行うhaskellプログラムを書いてみたいです。設定はData.Mapで、Readerに注入されます。また、設定項目が見つからないときは、読み込みを中断する必要があります。停止しただけで、エラーメッセージは必要ありません。だから私はただのモナド(モナドではない)がほしい。ReaderTまたはReaderを使用しますか?

問題は、2つのモナド(ReaderT MaybeまたはMaybeT Reader)をどのように積み重ねるべきですか?

答えて

4

最後に私はそれを理解します。どちらもOKです。

すべての設定項目の値が単なるIntであると仮定します。

MaybeT (Reader (\r -> Just 123)) 

か::

のような値を持つことになります

ReaderT (\r -> Just 123) 

または

ReaderT (\r -> Nothing) 

ReaderT ConfigMap Maybe Intは次のように値を持っています

どちらかといえば、最初にいくつかの読み込みを行い、読み込みがNothingを返すかどうかに応じて続行するかどうかを決定できます。値は異なる外形を持ちますが、同じ機能性を持ちます。ここ

私の小さなデモ:

import qualified Data.Map as M 
import Control.Monad 
import Control.Monad.Reader 
import Control.Monad.Trans 
import Control.Monad.Trans.Maybe 

type Config = M.Map String Int 

getConfig :: String -> MaybeT (Reader Config) Int 
getConfig key = MaybeT $ do 
    m <- ask 
    return $ M.lookup key m 

readAll :: Config -> Maybe (Int, Int) 
readAll m = 
    let r = runMaybeT $ do 
     a <- getConfig "a" 
     b <- getConfig "b" 
     return (a, b) 
    in runReader r m 

main :: IO() 
main = do 
    putStrLn $ show (readAll $ M.fromList [("x", 3), ("b", 4)]) 

私の第二のデモ:

import qualified Data.Map as M 
import Control.Monad 
import Control.Monad.Reader 
import Control.Monad.Trans 
import Control.Monad.Trans.Maybe 

type Config = M.Map String Int 

getConfig :: String -> ReaderT Config Maybe Int 
getConfig key = ReaderT $ \r -> M.lookup key r 

readAll :: Config -> Maybe (Int, Int) 
readAll m = 
    let r = runReaderT $ do 
     a <- getConfig "a" 
     b <- getConfig "b" 
     return (a, b) 
    in r m 

main :: IO() 
main = do 
    putStrLn $ show (readAll $ M.fromList [("a", 3), ("b", 4)]) 
+2

あなたは 'newtype'コンストラクタなしタイプを展開すると、あなたはどちらをr'にアンロール見つける - >たぶん'、それは彼らが同じかもしれないという良いヒントです。しかし、モナド演算子が同じ型(例えば、型が同じであっても動作が異なる場合があります。 'ListT(State s)'と 'StateT s []'です。 (これは 'ListT'が壊れているからですが、これはこのような場合の良い例です!) – luqui

+1

' ReaderT Maybe'と 'MaybeT Reader'は本当に特別なペアです。そして、このようなペアを作るのは同じ "内部形状"です(すべての型コンストラクタとモナド値のラムダ( '\ a - >')を取り除いた後の残りのものです)。ところで、失敗する可能性のあるログ計算では、 'MaybeT Writer'と' WriterT Maybe'は異なります。前者は '(Nothing、最初のN行のログ)'で失敗し、後者は 'Nothing '。 – brk

関連する問題