无法将预期类型"[foo]"与实际类型"也许 [foo]"匹配

  • 本文关键字:foo 类型 也许 匹配 haskell monads
  • 更新时间 :
  • 英文 :


我有两种记录类型:

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}

somethingMaybe [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])

相关内容

最新更新