3
我想寫一個haskell程序閱讀配置,並做一些事情。該配置是一個Data.Map
並將被注入一個閱讀器。當我們找不到配置項時,讀數應該被中斷。剛剛停止,不需要錯誤消息。所以我只想要一個Maybe monad(不是monad)。使用ReaderT Maybe或MaybeT Reader?
問題是,我應該如何堆疊兩個monads,ReaderT Maybe
或MaybeT Reader
?
我想寫一個haskell程序閱讀配置,並做一些事情。該配置是一個Data.Map
並將被注入一個閱讀器。當我們找不到配置項時,讀數應該被中斷。剛剛停止,不需要錯誤消息。所以我只想要一個Maybe monad(不是monad)。使用ReaderT Maybe或MaybeT Reader?
問題是,我應該如何堆疊兩個monads,ReaderT Maybe
或MaybeT Reader
?
最後我弄明白了。他們都是好的。
假設每個配置項目的值只是一個Int。
的ReaderT ConfigMap Maybe Int
將具有象一個值:
ReaderT (\r -> Just 123)
或
ReaderT (\r -> Nothing)
的MaybeT (Reader ConfigMap) Int
將具有象一個值:
MaybeT (Reader (\r -> Just 123))
或:
MaybeT (Reader (\r -> Nothing))
無論如何,我們可以先做一些閱讀,然後決定是否繼續根據閱讀是否返回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)])
如果展開的類型,而'newtype'構造函數,你會發現他們都展開到的r - >也許',這是一個很好的暗示,他們可能是相同的。但是在某些情況下,monad操作符即使具有相同的類型也會有不同的行爲,例如, 'ListT(狀態s)'和'StateT s []'。 (這是因爲'ListT'有點破了......但是在這種情況下就是一個很好的例子!) – luqui
我發現'ReaderT Maybe'和'MaybeT Reader'確實是一對特殊的對。而像這樣的一對是相同的「內部形狀」(除去所有類型的構造函數和monad值的lambda('\ a - >')之後的剩餘部分)。順便說一下,對於一個可能失敗的日誌計算,'MaybeT Writer'和'WriterT Maybe'可能會有所不同:前者會以'(Nothing,「前N行日誌)失敗,而後者只會以'Nothing '。 – brk