json - Haskell - 如何将基于管道的 JSON 转换为数据记录?
问题描述
我正在构建一个强化学习库,我想通过管道 JSON 将某些实例信息传递到可执行文件中。
使用aeson
's Simplest.hs
,我可以让以下基本示例按预期工作。请注意,参数是Main.hs
作为String
params
占位符的。
我试图修改Main.hs
,所以我会通过管道从 JSON 文件中输入 Nim 游戏参数,getContents
但我遇到了预期的问题。我试图尽可能多地阅读有关 IO 的信息,但无法弄清楚如何提升我的 JSON 解析方法来处理 IO。[Char]
IO String
我将如何修改以下内容以便可以使用管道输入的 JSON?
主文件
module Main where
import qualified System.Random as Random
import qualified Data.ByteString.Lazy.Char8 as BL
import qualified Games.Engine as Engine
import qualified Games.IO.Nim as NimIO
import qualified Games.Rules.Nim as Nim
import qualified Games.Learn.ValueIteration as VI
main :: IO ()
main = do
let params = "{\"players\":[\"Bob\", \"Alice\", \"Charlie\"], \"initialPiles\": [3, 4, 5], \"isMisere\": false}"
let result = NimIO.decode $ BL.pack params :: Maybe NimIO.NimGame
case result of
Nothing -> putStrLn "Parameter errors."
Just game -> do
putStrLn "Let's play some Nim! Remainder of code omitted"
Games.IO.Nim.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Games.IO.Nim
( decode
, NimGame
, players
, initialPiles
, isMisere
) where
import Control.Applicative (empty)
import qualified Data.ByteString.Lazy.Char8 as BL
import Data.Aeson
( pairs,
(.:),
object,
FromJSON(parseJSON),
Value(Object),
KeyValue((.=)),
ToJSON(toJSON, toEncoding),
decode)
data NimGame = NimGame
{ players :: [String]
, initialPiles :: [Int]
, isMisere :: Bool
} deriving (Show)
instance ToJSON NimGame where
toJSON (NimGame playersV initialPilesV isMisereV) = object [ "players" .= playersV,
"initialPiles" .= initialPilesV,
"isMisere" .= isMisereV]
toEncoding NimGame{..} = pairs $
"players" .= players <>
"initialPiles" .= initialPiles <>
"isMisere" .= isMisere
instance FromJSON NimGame where
parseJSON (Object v) = NimGame <$>
v .: "players" <*>
v .: "initialPiles" <*>
v .: "isMisere"
parseJSON _ = empty
Main.hs
产生编译错误的替代方案
module Main where
import qualified System.Random as Random
import qualified Data.ByteString.Lazy.Char8 as BL
import qualified Games.Engine as Engine
import qualified Games.IO.Nim as NimIO
import qualified Games.Rules.Nim as Nim
import qualified Games.Learn.ValueIteration as VI
main :: IO ()
main = do
--let params = "{\"players\":[\"Bob\", \"Alice\", \"Charlie\"], \"initialPiles\": [3, 4, 5], \"isMisere\": false}"
let params = getContents
let result = NimIO.decode $ BL.pack params :: Maybe NimIO.NimGame
case result of
Nothing -> putStrLn "Parameter errors."
Just game -> do
putStrLn "Let's play some Nim!"
编译错误
(base) randm@pearljam ~/Projects/gameshs $ stack build
gameshs-0.1.0.0: unregistering (local file changes: app/Nim.hs)
gameshs> configure (lib + exe)
Configuring gameshs-0.1.0.0...
gameshs> build (lib + exe)
Preprocessing library for gameshs-0.1.0.0..
Building library for gameshs-0.1.0.0..
Preprocessing executable 'nim-exe' for gameshs-0.1.0.0..
Building executable 'nim-exe' for gameshs-0.1.0.0..
[2 of 2] Compiling Main
/home/randm/Projects/gameshs/app/Nim.hs:17:41: error:
• Couldn't match expected type ‘[Char]’
with actual type ‘IO String’
• In the first argument of ‘BL.pack’, namely ‘params’
In the second argument of ‘($)’, namely ‘BL.pack params’
In the expression:
NimIO.decode $ BL.pack params :: Maybe NimIO.NimGame
|
17 | let result = NimIO.decode $ BL.pack params :: Maybe NimIO.NimGame
| ^^^^^^
-- While building package gameshs-0.1.0.0 (scroll up to its section to see the error) using:
/home/randm/.stack/setup-exe-cache/x86_64-linux-tinfo6/Cabal-simple_mPHDZzAJ_3.2.1.0_ghc-8.10.4 --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0 build lib:gameshs exe:nim-exe --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
解决方案
getContents
返回的不是String
您显然期望的 a ,而是IO String
,它是一个“程序”,执行时将产生 a String
。因此,当您尝试使用 解析此程序时decode
,这当然行不通:decode
解析 aString
时,它无法解析程序。
那么如何执行这个程序来获取String
? 有两种方法:要么让它成为另一个程序的一部分,要么调用它main
,它成为你的入口点。
在您的情况下,明智的做法是成为getContent
您的main
程序的一部分。为此,请使用左箭头<-
,如下所示:
main = do
params <- getContents
let result = NimIO.decode $ BL.pack params :: Maybe NimIO.NimGame
...
推荐阅读
- reactjs - reactjs中的蚂蚁设计警报位置
- mysql - 几秒钟后是否可以清空某些mysql数据?
- json - 试图了解如何处理用户数据。或者可能是措辞更好的用户输入
- excel-formula - 文本范围的百分位数
- python - 如何使用 Python 导入使用逗号作为十进制的 Excel 工作表?
- git - Dbeaver GitHub - 提交推送期间可能的对象级别锁定?
- kubernetes - Argo 模板无法从输出文件位置读取
- pycharm - 在 PyCharm 中的测试期间打印测试输出
- active-directory - 纯Azure AD加入windows 10智能卡windows登录
- c++ - 此 c++ 代码中的 Segfault 错误在哪里?