【问题标题】:Reading YAML lists of objects in Haskell在 Haskell 中读取对象的 YAML 列表
【发布时间】:2014-01-22 19:42:43
【问题描述】:

假设这个 YAML(保存在一个名为 users.yml 的文件中):

- id: 1
  name: Unknown user
  reputation: 0

- id: 2
  name: Foo bar
  reputation: 4

这个 Haskell data 类型:

data MyUser = MyUser {id :: Int,
                      name :: String,
                      reputation :: Int}
                      deriving (Show)

我想使用 yaml 库将 YAML 读入 [MyUser]。我该怎么做?

【问题讨论】:

    标签: parsing haskell yaml


    【解决方案1】:

    您需要按照Data.Yaml documentation 中的说明创建一个FromJSON 实例(请注意,这称为FromJSON,因为yaml 派生自Aeson 库)。

    之前讨论过 Aeson 的类似问题 here,而讨论了 Haskell YAML 库的选择 here

    这是一个将 YAML 文件转换为 [MyUser] 的最小工作示例:

    {-# LANGUAGE OverloadedStrings #-}
    import Data.Yaml
    import Control.Applicative -- <$>, <*>
    import Data.Maybe (fromJust)
    
    import qualified Data.ByteString.Char8 as BS
    
    data MyUser = MyUser {id :: Int,
                          name :: String,
                          reputation :: Int}
                          deriving (Show)
    
    instance FromJSON MyUser where
        parseJSON (Object v) = MyUser <$>
                               v .: "id" <*>
                               v .: "name" <*>
                               v .: "reputation"
        -- A non-Object value is of the wrong type, so fail.
        parseJSON _ = error "Can't parse MyUser from YAML/JSON"
    
    main = do
             ymlData <- BS.readFile "users.yml"
             let users = Data.Yaml.decode ymlData :: Maybe [MyUser]
             -- Print it, just for show
             print $ fromJust users
    

    【讨论】:

    • 我无法让它工作:/app/Main.hs:21:5: error: • Couldn't match type ‘Yaml.Value’ with ‘[Char]’ Expected type: unordered-containers-0.2.8.0:Data.HashMap.Base.HashMap text-1.2.2.1:Data.Text.Internal.Text String Actual type: Yaml.Object • In the second argument of ‘(&lt;$&gt;)’, namely ‘v’ In the first argument of ‘(.:)’, namely ‘Transaction &lt;$&gt; v’ In the first argument of ‘(.:)’, namely ‘(.:) Transaction &lt;$&gt; v "entryDate" &lt;*&gt; v’
    • @adius 我无法复制。 cabal sandbox init ; cabal install yaml ; cabal exec runghc index.hs 其中index.hs 是答案中列出的代码,为我正确生成[MyUser {id = 1, name = "Unknown user", reputation = 0},MyUser {id = 2, name = "Foo bar", reputation = 4}]。也许您可以尝试cabal update 并更改软件包版本?
    • 问题是我没有从Data.Yaml导入.:。我以为是Control.Applicative导出的函数。不幸的是,编译器错误在这方面并没有真正的帮助?
    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多