使用 Aeson 从输入参数解码 json 时出现问题
Problem decoding json from input args with Aeson
我正在尝试编写一个 Haskell 程序,该程序需要 Json 字符串作为输入。预期 Json 是 Person
个对象的列表。我想通过默认为空列表的 Json 来处理用户未提供输入的情况。
似乎我 运行 陷入 ByteString 和 String 之间的类型转换问题。我确实打开了 OverloadedStrings
,但它似乎对这里没有帮助。这是简化的代码。
{-# LANGUAGE OverloadedStrings #-}
import GHC.Generics
import System.Environment
import Data.Aeson
import Data.Maybe (fromMaybe, listToMaybe)
import Data.Text (Text)
data Person = Person { pName :: Text, pAge :: Int } deriving (Show,
Generic)
instance ToJSON Person
instance FromJSON Person
main :: IO (Maybe [Person])
main = do
args <- getArgs
arg1 <- pure $ (fromMaybe "[]" (listToMaybe args))
-- let arg1 = "[{\"pName\": \"James\", \"pAge\": 30}]"
return $ decode arg1 :: IO (Maybe [Person])
我得到的错误是:
• Couldn't match type ‘[Char]’
with ‘Data.ByteString.Lazy.Internal.ByteString’
Expected type: Data.ByteString.Lazy.Internal.ByteString
Actual type: String
• In the first argument of ‘decode’, namely ‘arg1’
In the second argument of ‘($)’, namely ‘decode arg1’
In a stmt of a 'do' block:
return $ decode arg1 :: IO (Maybe [Person])
如果我取消注释 let arg1
以模拟 arg1 应该是什么,然后代码编译。
问题是 getArgs
returns 一个 [String]
,而不是 [ByteString]
。 decode
真的想要一个 ByteString
作为输入。
OverloadedStrings
对此没有帮助;它只影响代码中的字符串文字,不影响外部输入。这就是带有硬编码参数 (let arg1 = "[{\"pName\": \"James\", \"pAge\": 30}]"
) 的版本起作用的原因:arg1
自动变为 ByteString
以使 decode arg1
起作用,但 getArgs
具有不兼容的类型。
一个可能的修复方法是以某种方式将命令行字符串编码为字节,但似乎 an easier alternative:
import System.Posix.Env.ByteString (getArgs)
这给了你一个
getArgs :: IO [ByteString]
(我还没有实际测试过这段代码;您可能还必须使用 decodeStrict
而不是 decode
。)
我正在尝试编写一个 Haskell 程序,该程序需要 Json 字符串作为输入。预期 Json 是 Person
个对象的列表。我想通过默认为空列表的 Json 来处理用户未提供输入的情况。
似乎我 运行 陷入 ByteString 和 String 之间的类型转换问题。我确实打开了 OverloadedStrings
,但它似乎对这里没有帮助。这是简化的代码。
{-# LANGUAGE OverloadedStrings #-}
import GHC.Generics
import System.Environment
import Data.Aeson
import Data.Maybe (fromMaybe, listToMaybe)
import Data.Text (Text)
data Person = Person { pName :: Text, pAge :: Int } deriving (Show,
Generic)
instance ToJSON Person
instance FromJSON Person
main :: IO (Maybe [Person])
main = do
args <- getArgs
arg1 <- pure $ (fromMaybe "[]" (listToMaybe args))
-- let arg1 = "[{\"pName\": \"James\", \"pAge\": 30}]"
return $ decode arg1 :: IO (Maybe [Person])
我得到的错误是:
• Couldn't match type ‘[Char]’
with ‘Data.ByteString.Lazy.Internal.ByteString’
Expected type: Data.ByteString.Lazy.Internal.ByteString
Actual type: String
• In the first argument of ‘decode’, namely ‘arg1’
In the second argument of ‘($)’, namely ‘decode arg1’
In a stmt of a 'do' block:
return $ decode arg1 :: IO (Maybe [Person])
如果我取消注释 let arg1
以模拟 arg1 应该是什么,然后代码编译。
问题是 getArgs
returns 一个 [String]
,而不是 [ByteString]
。 decode
真的想要一个 ByteString
作为输入。
OverloadedStrings
对此没有帮助;它只影响代码中的字符串文字,不影响外部输入。这就是带有硬编码参数 (let arg1 = "[{\"pName\": \"James\", \"pAge\": 30}]"
) 的版本起作用的原因:arg1
自动变为 ByteString
以使 decode arg1
起作用,但 getArgs
具有不兼容的类型。
一个可能的修复方法是以某种方式将命令行字符串编码为字节,但似乎 an easier alternative:
import System.Posix.Env.ByteString (getArgs)
这给了你一个
getArgs :: IO [ByteString]
(我还没有实际测试过这段代码;您可能还必须使用 decodeStrict
而不是 decode
。)