我有两种记录类型:
data Attribute = Attr {
attName :: Text,
attValue :: Text
} deriving (Show, Generic)
data Attributes = Attrs {
attributes :: [Attribute]
} deriving (Show, Generic)
在main
中,contents
值包含一个Maybe [Attribute]
,我正试图将其铲入Attrs
构造函数:
main :: IO ()
main = do
bytes <- readFile "data/file.json"
contents <- pure (decode bytes :: Maybe [Attribute])
let attributes = Attrs { attributes = contents }
print attributes
运行此操作会产生以下错误:
• Couldn't match expected type ‘[Attribute]’
with actual type ‘Maybe [Attribute]’
• In the ‘attributes’ field of a record
In the expression: Attrs {attributes = contents}
当something
是Maybe [Attribute]
而不是直接是[Attribute]
时,如何应用Attrs { attributes = something }
构造函数?
您需要处理解码失败的Nothing
情况。这是一种可能的方法。
main :: IO ()
main = do
bytes <- readFile "data/file.json"
case decode bytes :: Maybe [Attribute] of
Nothing -> putStrLn "Error: can't decode the file!"
Just contents -> do
let attributes = Attrs { attributes = contents }
print attributes
:: Maybe [Attribute]
部分可能是多余的,因为编译器可以从程序的其余部分推断出该类型。尽管如此,你可能还是想把它留在那里,让代码对人类更可读。
请注意,decode
库函数被设计为返回Maybe [Attribute]
而不是[Attribute]
,这样它既可以报告错误(解码失败(,也可以强制调用方处理此类错误。以这种方式,程序员不能再";忘记";以检查错误,因为类型不匹配。
如果decode
不这样做,decode
将需要使程序崩溃(非常不方便(或报告一个伪值(例如[]
(,这可能会被误认为是实际输入,并允许调用方忘记检查错误。
如果你想危险地生活:
let Just contents = (decode bytes :: Maybe [Attribute])