我正在尝试编写一个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应该是什么,则代码将编译。
答案 0 :(得分:2)
问题是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
。)