首页 > 解决方案 > 在 Haskell 的堆栈项目文件夹中放置输入 JSON 文件的位置?

问题描述

我是 Haskell 和 Stack 的新手。这将是我在 Haskell 中最初的几个程序之一。因此,到目前为止无法使其正常工作。

  1. 在一个小型 Haskell 程序的帮助下,获得了一个 JSON 文件(来自网站的统计数据的简短摘要 - 嵌套 JSON 格式)。我在那个堆栈项目的“App”文件夹中找到了它。

  2. 在下一个程序/堆栈项目中,我们尝试解析 data.json(在上一个程序中获得)并仅获取在 ghci 中显示/打印的统计数据的特定部分 - 以列表格式(借助 forM_ [decoded -JSON's-certain-portion-of-data-in-list-format](打印。名称))。由于 'decode-JSON' 函数(来自 Data.Aseon)会产生 Maybe 格式的结果,我们也进行模式匹配以显示 'Error - loading data' 以防结果为空;并且,当有 Just 数据时执行 forM_。

  3. 我的问题是 - 代码编译;但是,即使我将 data.json 放在这个特定堆栈项目的文件夹中,也会显示“错误 - 加载失败”。

我没有在 cabal 文件中进行任何手动更新。Stack 不允许我对 cabal 文件进行任何手动更改,并要求我删除 cabal 或 package.yaml。当 package.yaml 使用“依赖项和扩展”详细信息等更新时,堆栈不会抛出此类错误/警告。因此,我在 package.yaml 中更新了这个 data.json 信息。

(虽然我不确定 stack-proj-folder 中哪个位置正确,应该放置输入数据。

但是,不管所有这些地方,我都尝试过放置输入 data.json 文件 - 以便堆栈访问和读取,它似乎并没有这样工作。编译后的代码总是返回“加载数据时出错”——表明 decodeJSON 函数没有返回任何内容/没有数据——即使文件/数据格式是有效的。(它不是手动准备的文件 - 由于手动格式化可能会发生错误;它只是一个系统从网站生成的 JSON 文件数据。并且,它具有用于解码的有效数据)

我附上

在 packagae.yaml 的顶部:

   extra-source-files:
    - README.md
    - ChangeLog.md

   data-files:
    - data.json

名为“data.json”的文件中的数据:

    {"metadata":{"resultset":{"offset":1,"count":11,"limit":25}},"results":[{"uid":"gov.noaa.ncdc:C00861","mindate":"1763-01-01","maxdate":"2021-07-02","name":"Daily Summaries","datacoverage":1,"id":"GHCND"},{"uid":"gov.noaa.ncdc:C00946","mindate":"1763-01-01","maxdate":"2021-06-01","name":"Global Summary of the Month","datacoverage":1,"id":"GSOM"},{"uid":"gov.noaa.ncdc:C00947","mindate":"1763-01-01","maxdate":"2021-01-01","name":"Global Summary of the Year","datacoverage":1,"id":"GSOY"},{"uid":"gov.noaa.ncdc:C00345","mindate":"1991-06-05","maxdate":"2021-07-02","name":"Weather Radar (Level II)","datacoverage":0.95,"id":"NEXRAD2"},{"uid":"gov.noaa.ncdc:C00708","mindate":"1994-05-20","maxdate":"2021-07-02","name":"Weather Radar (Level III)","datacoverage":0.95,"id":"NEXRAD3"},{"uid":"gov.noaa.ncdc:C00821","mindate":"2010-01-01","maxdate":"2010-01-01","name":"Normals Annual/Seasonal","datacoverage":1,"id":"NORMAL_ANN"},{"uid":"gov.noaa.ncdc:C00823","mindate":"2010-01-01","maxdate":"2010-12-31","name":"Normals Daily","datacoverage":1,"id":"NORMAL_DLY"},{"uid":"gov.noaa.ncdc:C00824","mindate":"2010-01-01","maxdate":"2010-12-31","name":"Normals Hourly","datacoverage":1,"id":"NORMAL_HLY"},{"uid":"gov.noaa.ncdc:C00822","mindate":"2010-01-01","maxdate":"2010-12-01","name":"Normals Monthly","datacoverage":1,"id":"NORMAL_MLY"},{"uid":"gov.noaa.ncdc:C00505","mindate":"1970-05-12","maxdate":"2014-01-01","name":"Precipitation 15 Minute","datacoverage":0.25,"id":"PRECIP_15"},{"uid":"gov.noaa.ncdc:C00313","mindate":"1900-01-01","maxdate":"2014-01-01","name":"Precipitation Hourly","datacoverage":1,"id":"PRECIP_HLY"}]}

代码 :

module Main where

import Data.Aeson
import qualified Data.Text as T
import qualified Data.ByteString.Lazy as B
import qualified Data.ByteString.Lazy.Char8 as BC
import GHC.Generics
import Control.Monad
import Control.Applicative
import System.IO

data.json 中数据的数据类型声明:

    data NOAAResult = NOAAResult
                { uid :: T.Text
                , mindate :: T.Text
                , maxdate :: T.Text
                , name :: T.Text
                , datacoverage :: Int
                , resultId :: T.Text
                } deriving Show

    instance FromJSON NOAAResult where
        parseJSON (Object v) =
                        NOAAResult <$> v .: "uid"
                            <*> v .: "mindate"
                            <*> v .: "maxdate"
                            <*> v .: "name"
                            <*> v .: "datacoverage"
                            <*> v .: "id"                  

    data Resultset = Resultset
                { offset :: Int
                , count :: Int
                , limit :: Int
                } deriving (Show,Generic)
              
    instance FromJSON Resultset
              
    data Metadata = Metadata
                {
                resultset :: Resultset
                } deriving (Show,Generic)
              
    instance FromJSON Metadata

    data NOAAResponse = NOAAResponse
                { metadata :: Metadata
                , results :: [NOAAResult]
                } deriving (Show,Generic)
              
    instance FromJSON NOAAResponse

IO 动作:

    printResults :: Maybe [NOAAResult] -> IO ()
    printResults Nothing = print "error loading data"
    printResults (Just results) = do
    forM_ results (print . name)


    main :: IO ()
    main = do
     jsonData <- B.readFile "data.json"
     let noaaResponse = decode jsonData :: Maybe NOAAResponse
     let noaaResults = results <$> noaaResponse
     printResults noaaResults

请求指导/帮助。

谢谢你。

标签: jsonhaskellhaskell-stack

解决方案


如果我将您的示例作为硬编码字符串运行,则会eitherDecode得到以下信息:

Left "Error in $.results[3].datacoverage: parsing Int failed, value is either floating or will cause over or underflow 0.95"

所以,似乎类型不应该datacoverage是:DoubleInt

data NOAAResult = NOAAResult
            { uid :: T.Text
            , mindate :: T.Text
            , maxdate :: T.Text
            , name :: T.Text
            , datacoverage :: Double
            , resultId :: T.Text
            } deriving Show

这有帮助吗?


推荐阅读