{-# LANGUAGE DuplicateRecordFields #-}
resolveProjectConfig :: IO (Maybe ProjectConfig)
config :: IO ()
config = do
config <- resolveProjectConfig
case config of
Just c -> putStrLn (name c)
Nothing -> putStrLn "broken"
GHC 似乎知道在
Just c
中 c 是一个 ProjectConfig
,但在 putStrLn (name c)
中我收到错误“不明确的出现名称。它可以指的是字段名称...[其他带有名称字段的内容列表]”。当然,如果它知道
c
是什么,它应该能够选择正确的名称函数?有没有办法让它弄清楚,而不添加 c :: ProjectConfig
? 最佳答案
这是 GHC 的当前限制。我们需要编写 name (c :: ProjectConfig)
来消除歧义。不是很方便。
作为替代方案,您可以对信息更丰富的模式进行模式匹配(如 Willem Van Onsem 所建议的):
case config of
Just (ProjectConfig {name=n}) -> putStrLn n
这将消除歧义,因为
name
仅用于 ProjectConfig
之后的模式中,因此它被接受。另一种更麻烦的替代方法是使用自定义类型类。假设所有
name
字段都是字符串,我们可以使用:class HasName a where
getName :: a -> String
instance HasName ProjectConfig where
getName = name
instance HasName Other where -- for other types having the same field
getName = name
config :: IO ()
config = do
config <- resolveProjectConfig
case config of
Just c -> putStrLn (getName c)
...
(为什么这不是在引擎盖下自动完成的,这超出了我的理解。)
关于haskell - 为什么 GHC 不能确定在这个 case 语句中使用哪个字段?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57181359/