2013-09-28 53 views
2

讓我們定義一個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 xb ~ Maybe x),但編譯器不會產生Overlapping Instances錯誤。如何使用-XNoOverlappingInstances

順便說一句,它是一種安全可用的方法來定義這種方法崩潰嵌套Maybe

回答

5

我認爲這個問題可能是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標誌,並且我認爲該行爲將與您最初的預期相同:重疊實例標誌使工作與不工作之間的差異變得不同。

相關問題