让我们定义一个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
吗?