我OverlappingInstances
用来制作一个漂亮的打印类,Show
只要我没有为某种类型提供自定义实例,它就会默认使用。
where
由于某种原因,每当您使用子句或let
表达式时,这似乎都会中断。
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class View a where
view :: a -> String
instance {-# OVERLAPS #-} Show a => View a where
view = show
-- Works just fine
instance (View a, View b) => View (a, b) where
view (a, b) = "(" ++ view a ++ ", " ++ view b ++ ")"
-- Does not work
instance (View a, View b) => View (a, b) where
view (a, b) = "(" ++ a' ++ ", " ++ b' ++ ")"
where
a' = view a
b' = view b
-- Does not work
instance (View a, View b) => View (a, b) where
view (a, b) = let
a' = view a
b' = view b
in "(" ++ a' ++ ", " ++ b' ++ ")"
现在,如果我删除默认的重叠实例,所有其他实例都可以正常工作。
我希望有人可以向我解释为什么会发生这种情况,还是只是一个错误?
我为每个人得到的具体错误是:
Could not deduce (Show a) arising from a use of ‘view’ from the context (View a, View b) bound by the instance declaration at ...
Could not deduce (Show b) arising from a use of ‘view’ from the context (View a, View b) bound by the instance declaration at ...
因此,出于某种原因where
/let
正在欺骗类型检查器认为View
requires Show
,而实际上不需要。