Data.ConfigFile 没有使用 get 的 Bool 实例
Data.ConfigFile not using the Bool instance of get
根据https://hackage.haskell.org/package/ConfigFile-1.0.5/docs/Data-ConfigFile.html,该包将转换配置中的一个值。文件到布尔。以下代码:
{-# LANGUAGE FlexibleContexts #-}
import qualified Data.ConfigFile as DC
import qualified Control.Monad.Except as CME
-- | The foundation object
data JRState = JRState {
secureOnly :: Bool -- ^ restrict connections to HTTPS
}
main :: IO ()
main = (CME.runExceptT $ pipe (JRState False)) >>= estate
estate :: Show t => Either t JRState -> IO ()
estate (Right state) = return ()
estate (Left err) = do
putStrLn $ "<<" ++ show err ++ ">>"
return ()
pipe :: (CME.MonadError DC.CPError m, CME.MonadIO m) => JRState -> m JRState
pipe site = do
cp <- CME.join $ CME.liftIO $ return $ DC.readstring DC.emptyCP{DC.optionxform=id} "secureSession = True\n"
DC.get cp "DEFAULT" "secureSession" >>= return . nubb where
nubb (Left err) = error err
nubb (Right value) = site{secureOnly = value}
当运行时,产生
<<(ParseError "couldn't parse value True from (DEFAULT/secureSession)","genericget")>>
这显然来自 estate 中的 putStrLn。但我希望在 pipe 和 nubb(愚蠢的名字,我知道)中提取值会强制使用布尔上下文,从而强制将 True 字符串转换为 Bool。我试过 1 和是,结果相同。怎么回事?
这是一个具有类似问题行为的更小的程序:
import qualified Data.ConfigFile as DC
import qualified Control.Monad.Except as CME
main = CME.runExceptT pipe >>= print
pipe = do
cp <- DC.readstring DC.emptyCP{DC.optionxform=id} "secureSession = True\n"
DC.get cp "DEFAULT" "secureSession" >>= nubb
nubb :: Either String Bool -> m Bool
nubb = undefined
当它被简化为这种基本形式时,很明显出了什么问题:你要求 DC.get
到 return 和 Either String Bool
而实际上你应该只是要求它 return 一个 Bool
。精简版的简单修复是完全消除该行的 >>= nubb
部分;应该很容易将此修复程序转换回更大的上下文。
根据https://hackage.haskell.org/package/ConfigFile-1.0.5/docs/Data-ConfigFile.html,该包将转换配置中的一个值。文件到布尔。以下代码:
{-# LANGUAGE FlexibleContexts #-}
import qualified Data.ConfigFile as DC
import qualified Control.Monad.Except as CME
-- | The foundation object
data JRState = JRState {
secureOnly :: Bool -- ^ restrict connections to HTTPS
}
main :: IO ()
main = (CME.runExceptT $ pipe (JRState False)) >>= estate
estate :: Show t => Either t JRState -> IO ()
estate (Right state) = return ()
estate (Left err) = do
putStrLn $ "<<" ++ show err ++ ">>"
return ()
pipe :: (CME.MonadError DC.CPError m, CME.MonadIO m) => JRState -> m JRState
pipe site = do
cp <- CME.join $ CME.liftIO $ return $ DC.readstring DC.emptyCP{DC.optionxform=id} "secureSession = True\n"
DC.get cp "DEFAULT" "secureSession" >>= return . nubb where
nubb (Left err) = error err
nubb (Right value) = site{secureOnly = value}
当运行时,产生
<<(ParseError "couldn't parse value True from (DEFAULT/secureSession)","genericget")>>
这显然来自 estate 中的 putStrLn。但我希望在 pipe 和 nubb(愚蠢的名字,我知道)中提取值会强制使用布尔上下文,从而强制将 True 字符串转换为 Bool。我试过 1 和是,结果相同。怎么回事?
这是一个具有类似问题行为的更小的程序:
import qualified Data.ConfigFile as DC
import qualified Control.Monad.Except as CME
main = CME.runExceptT pipe >>= print
pipe = do
cp <- DC.readstring DC.emptyCP{DC.optionxform=id} "secureSession = True\n"
DC.get cp "DEFAULT" "secureSession" >>= nubb
nubb :: Either String Bool -> m Bool
nubb = undefined
当它被简化为这种基本形式时,很明显出了什么问题:你要求 DC.get
到 return 和 Either String Bool
而实际上你应该只是要求它 return 一个 Bool
。精简版的简单修复是完全消除该行的 >>= nubb
部分;应该很容易将此修复程序转换回更大的上下文。