parsing - 展开 Aeson 示例,如何使用值数组?

标签 parsing haskell aeson

我试图更多地了解 Haskell,并成功地遵循了 Aeson 的例子。我现在正在尝试适应它,但我缺乏并且我确信这是一个相当基本的理解。如果重要的话,我正在使用 IHaskell-aeson 包在 Jupyter Lab 设置中执行此操作。
初始示例假设输入 JSON 文件由单个简单对象组成。输出解析对象并提供一个小的 greet信息。

{
  "name": "Johann Carl Freidrich Guass",
  "nationality": "German",
  "born": "30 April 1777",
  "died": "23 February 1855"
}
输出:Johann Carl Freidrich Guass was born 30 April 1777我想扩展它以使用此 JSON:
{
  "mathematicians": [
    { "name".... },
    { "name".... },
    { "name".... },
    { "name".... }
  ]
}
这是我现在的代码,我在第一个版本中留下了评论(:extension 用于 IHaskell/Jupyter):
:extension OverloadedStrings

import qualified Data.ByteString.Lazy as B
import Control.Monad (mzero)
import Data.Foldable (toList)
import Data.Aeson.Types (Parser)

data Mathematicians = Mathematicians
                    { mathematicians :: [Mathematician]
                    } deriving (Show)
data Mathematician = Mathematician 
                     { name :: String
                     , nationality :: String
                     , born :: String
                     , died :: Maybe String
                     } deriving (Show)
                     
instance A.FromJSON Mathematician where
    parseJSON (A.Object v) = Mathematician
                         <$> (v A..: "name")
                         <*> (v A..: "nationality")
                         <*> (v A..: "born")
                         <*> (v A..:? "died")
    parseJSON _ = mzero
                     
instance A.FromJSON Mathematicians where
    parseJSON (A.Object v) = do
        ms <- v A..: "mathematicians"
        fmap Mathematicians $ A.parseJSON ms
    parseJSON _ = mzero
                         
input <- B.readFile "mathematicians.json"

greet m = (show.name) m ++ 
          " was born " ++ 
          (show.born) m

-- let mm = A.decode input :: Maybe Mathematician
-- case mm of
--     Nothing -> print "error parsing JSON"
--     Just m -> (putStrLn.greet) m

let mms = A.decode input :: Maybe Mathematicians
case mms of
    Nothing -> print "error parsing JSON"
    Just ms -> print ms
打印ms给了我以下内容,这让我相信解析可能正在工作:

Mathematicians {mathematicians = [Mathematician {name = "Johann Carl Friedrich Gauss", nationality = "German", born = "30 April 1777", died = Just "23 February 1855"},Mathematician {name = "Leonhard Euler", nationality = "German", born = "15 April 1707", died = Just "18 September 1783"},Mathematician {name = "William Rowan Hamilton", nationality = "Irish", born = "3 August 1805", died = Just "2 September 1865"},Mathematician {name = "Terence Chi-Shen Tao", nationality = "Australia", born = "17 July 1975", died = Nothing}]}


此外,故意在 Mathematician 中插入一个错字解析器导致 error parsing JSON消息,所以手指交叉它似乎解析工作。
但是,我不明白如何访问个人Mathematician元素,然后运行 ​​greet在他们身上依次。
我试过这样打印:print (fmap greet ms)并得到
<interactive>:3:34: error:
    • Couldn't match expected type ‘f0 Mathematician’ with actual type ‘Mathematicians’
    • In the second argument of ‘fmap’, namely ‘ms’
      In the first argument of ‘print’, namely ‘(fmap greet ms)’
      In the expression: print (fmap greet ms)
使用 print (map greet ms)反而:
<interactive>:3:33: error:
    • Couldn't match expected type ‘[Mathematician]’ with actual type ‘Mathematicians’
    • In the second argument of ‘map’, namely ‘ms’
      In the first argument of ‘print’, namely ‘(map greet ms)’
      In the expression: print (map greet ms)
我很抱歉地说,这两者都不是,我完全理解。

最佳答案

mmsMaybe Mathematicians ,这意味着它可能不存在 Mathematicians值(有点像其他语言中的 null)。所以你需要“进入”Maybe运行前 greet在列表中的数学家。fmap :: (a -> b) -> Maybe a -> Maybe b可以为你做这件事。我们要给fmap一个函数,它变成 Mathematicians成字符串列表(所以 aMathematiciansb[String] )。 fmap将检查 Maybe , 如果有值就运行函数,如果没有值就什么都不做。

greetMathematicians :: Maybe Mathematicians -> Maybe [String]
greetMathematicians mms = fmap (\ms -> [greet m | m <- mathematicians ms]) mms

关于parsing - 展开 Aeson 示例,如何使用值数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62938217/

相关文章:

json - 使用 lens-aeson 提取 JSON 字段时结合棱镜

python - 在 Python 中解析来自 http 请求的文本响应

haskell - 我怎样才能 "break"在 Haskell 中进行列表理解?

Haskell:执行包含在 Data.Dynamic 中的 IO 操作

haskell - 使用 Network.Browser 创建 cookie

haskell - 当使用 Aeson 解析 JSON 时,为什么 Maybe 在类型参数中会受到不同的处理?

ruby-on-rails - Rails XML 解析

java - 使用 java 解析 xml 字符串和修剪特定标签空间的最佳方法

jQuery Tablesorter - 自定义解析器不起作用

json - 有条件地将字段添加到 JSON 输出