Haskell的Stack项目文件夹内输入JSON文件应该放置在什么位置?
核心问题排查
你当前遇到decode返回Nothing的原因不是文件路径错误:如果文件找不到,B.readFile会直接抛出IO异常中断程序,不会走到打印加载错误的分支。问题出在NOAAResult类型的datacoverage字段声明错误:你将其定义为Int类型,但JSON中该字段存在0.95、0.25这类浮点值,Aeson无法将浮点值解析为Int,直接导致整个JSON结构解码失败。
修复方式:将NOAAResult定义中的datacoverage :: Int修改为datacoverage :: Double即可。
1. Stack项目数据文件存放与操作流程
分两种使用场景对应不同方案:
- 本地开发调试场景:仅自己本地运行、用ghci调试时,不需要额外配置。将
data.json放在项目根目录(和stack.yaml、package.yaml同级),在根目录执行stack run或者stack ghci即可,此时程序的默认工作目录就是项目根目录,写死"data.json"相对路径可以正常读取。 - 打包分发场景:需要将数据文件随编译好的程序一起打包发布时,才需要用到
data-files配置,配合自动生成的路径读取函数,避免不同系统、不同安装路径下文件找不到的问题。
2. 配置与代码调整方案
快速调试方案(适合个人本地测试)
- 将
data.json放在项目根目录 - 修正
datacoverage字段类型为Double - 在项目根目录执行
stack run即可正常输出结果。
规范打包方案(适合需要分发程序的场景)
- 在项目根目录新建
data文件夹(和app、src同级),将data.json放入该文件夹 - 修改
package.yaml的data-files配置:
data-files: - data/data.json
- 代码中引入自动生成的
Paths_<你的项目名>模块(模块名中的项目名取package.yaml中name字段的值,横杠要替换为下划线,比如项目名为noaa-data-parser,对应模块名为Paths_noaa_data_parser),修改main函数用getDataFileName获取文件的实际运行路径:
-- 导入自动生成的路径模块,替换为你实际的项目名 import Paths_noaa_data_parser main :: IO () main = do -- 自动获取data.json在运行环境中的实际路径 dataPath <- getDataFileName "data/data.json" jsonData <- B.readFile dataPath let noaaResponse = decode jsonData :: Maybe NOAAResponse let noaaResults = results <$> noaaResponse printResults noaaResults
- 不要忘记修正
datacoverage字段的类型为Double。
内容的提问来源于stack exchange,提问作者user16400316
相关产品推荐
相关产品推荐

