让我们定义一个collapse
函数,将任何可能嵌套的Maybe (Maybe (... a)...)
折叠为Maybe a
:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE IncoherentInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoOverlappingInstances #-}
{-# LANGUAGE TypeFamilies #-}
module MaybeCollapsable where
class M a b where
collapse :: Maybe a -> Maybe b
instance (a ~ b) => M a b where
collapse = id
instance M a b => M (Maybe a) b where
collapse Nothing = Nothing
collapse (Just a) = collapse a
效果很好
> collapse (Just (Just (Just 1)))
Just 1
虽然,很奇怪。这两个实例似乎都可以匹配特定情况(a ~ Maybe x
和b ~ Maybe x
),但编译器不会产生Overlapping Instances
错误。
如何使用-XNoOverlappingInstances
?
顺便说一下,定义这种折叠嵌套Maybe
的方法是一种安全可行的方法吗?
答案 0 :(得分:6)
我认为问题可能是IncoherentInstances
覆盖了NoOverlappingInstances
指令。如果删除IncoherentInstances
,则代码会出现重叠实例错误。 GHC手册对此并不清楚(http://www.haskell.org/ghc/docs/7.6.3/html/users_guide/type-class-extensions.html#instance-overlap),但这两个标志明确相关。
如果您关闭IncoherentInstances
并启用OverlappingInstances
,则代码可以正常运行。所以删除IncoherentInstances
标志,我认为行为将如您最初预期的那样:重叠实例标志使工作与不工作之间存在差异。