我的数据类型包含许多字段,如果不是由 JSON 配置文件手动指定,则应随机设置。我正在使用 Aeson 来解析配置文件。做这个的最好方式是什么?
目前,我将值设置为等于某个不可能的值,然后检查该值以进行编辑。
data Example = Example { a :: Int, b :: Int }
default = Example 1 2
instance FromJSON Example where
parseJSON = withObject "Example" $ \v -> Example
<$> (v .: "a" <|> return (a default))
<*> (v .: "b" <|> return (b default))
initExample :: Range -> Example -> IO Example
initExample range (Example x y) = do
a' <- if x == (a default) then randomIO range else return x
b' <- if y == (b default) then randomIO range else return y
return $ Example a' b'
我想要的是:
parseJSON = withObject "Example" $ \v -> Example
<$> (v .: "a" <|> return (randomRIO (1,10))
是否可以在 IO Monad 中定义解析器或沿某个随机生成器线程(最好使用 Aeson)?
好吧,我不知道这是否是一个好主意,并兼顾额外的事情IO
对于更大的开发来说,layer 肯定会令人沮丧,但是以下类型检查:
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative
import Data.Aeson
import System.Random
data Example = Example { a :: Int, b :: Int } deriving (Eq, Ord, Read, Show)
instance FromJSON (IO Example) where
parseJSON = withObject "Example" $ \v -> liftA2 Example
<$> ((pure <$> (v .: "a")) <|> pure (randomRIO (3, 4)))
<*> ((pure <$> (v .: "b")) <|> pure (randomRIO (5, 6)))
在最后两行的每一行中,第一行pure
is Int -> IO Int
,第二个是IO Int -> Parser (IO Int)
。在 ghci 中:
> sequence (decode "{}") :: IO (Maybe Example)
Just (Example {a = 4, b = 6})
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)