【问题标题】:Where to place input JSON file inside Haskell's stack project folder?在 Haskell 的堆栈项目文件夹中放置输入 JSON 文件的位置?
【发布时间】:2023-03-29 11:39:01
【问题描述】:

我是 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 放在这个特定堆栈项目的文件夹中,也会显示“错误 - 加载失败”。

  • 在主模块中添加了“import System.IO”。
  • 在 package.yaml 中添加了“Data-files: (/n)-data.json” - 在顶部,“extra-source-files”详细信息的正下方。

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

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

  • 我尝试将它作为元素之一放在项目的根文件夹中,以及 package.yaml、cabal 文件和 stack.yaml 等;

  • 我还放置了 data.json 文件的副本 - 在“app”文件夹中 - 以及 Main.hs 文件(因为这是前一个程序中堆栈放置的输出。因此,假设堆栈可能看起来考虑这个文件夹对于输入/输出文件,虽然我不确定,它似乎没有按预期工作);

  • 我还创建了一个名为“data”的附加文件夹(就像 src、app 和 test),并在其中放置了 data.json 文件的副本。虽然我没有在 package.yaml 中为这个新的“数据”文件夹提供任何描述,因为我不确定这样做的正确方法)

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

我附上

  • package.yaml 更新
  • data.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
  • 知道将输入数据文件放入haskell-stack的正确位置和正确过程将很有帮助。

  • 此外,在将数据文件放入相应的文件夹/路径后,需要在配置文件(如 cabal(或)package.yaml)和代码(如 import System.IO)中进行哪些更新 - 这样haskell 程序在从 stack-project 文件夹中识别输入数据文件并对其进行处理方面没有问题。 (在我的情况下,它会给出“加载数据时出错”消息 - 即使 data.json 输入文件放在 stack-proj 文件夹中。因此,我认为,我错过了正确的做法)

请求指导/帮助。

谢谢。

【问题讨论】:

    标签: json haskell haskell-stack


    【解决方案1】:

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

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

    所以,看来datacoverage 的类型应该是Double 而不是Int

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

    这有帮助吗?

    【讨论】:

    • 非常感谢!
    • 另外,我们应该手动将输入文件放在当前堆栈项目文件夹中吗?或者,有没有办法让haskell 查找来自外部文件夹(其他堆栈项目模块)的输入数据。在这种情况下,在 haskell 代码和配置文件(.yaml/cabal/etc)中添加该数据的过程是什么谢谢。
    • @user16400316 我认为在这种情况下最好的方法是让用户输入他们想要总结的data.json 文件的位置。如果您真的想将它与您的包捆绑在一起,那么您可以使用数据文件,请参阅此处的完整文档:cabal.readthedocs.io/en/3.4/…
    • 只需要一个 qn/help。当我尝试任一解码时,我的错误消息不像您的那样具有描述性。我刚收到parse error on input "'' `。就是这样。可能是什么原因。因为获取错误描述而询问可能会更容易快速识别问题。我记得之前也尝试过任何解码。但是,它是类似的通用错误消息 - 没有任何关于确切错误位置/详细信息的描述。如果您能猜到,可能是什么原因。谢谢。
    • 现在了解如何获取详细错误。还是非常感谢。很抱歉有多个问题。
    猜你喜欢
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 2022-01-08
    相关资源
    最近更新 更多