我正在尝试编写一个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
返回[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
。)