2013-08-03 65 views
3

以下是一個完美的編譯代碼:數據家庭和分型

data family DF a 
data instance DF Int = DFInt deriving (Show) 
data instance DF Char = DFChar deriving (Show) 

但是試圖獲得Typeable在下面給出了一個「重複實例聲明」錯誤:

data family DF a 
data instance DF Int = DFInt deriving (Typeable) 
data instance DF Char = DFChar deriving (Typeable) 

那麼,如何爲數據族衍生出Typeable?它有可能嗎?如果不是那麼爲什麼?

回答

1

如果使用-ddump-deriv看看推導的輸出,你看到每一個數據族實例聲明的是生產相同的instance Typeable1 DF

data family DF a 
data instance DF Int = DFInt deriving (Typeable) 
data instance DF Char = DFChar deriving (Typeable) 

instance Data.Typeable.Internal.Typeable1 Main.DF where 
    Data.Typeable.Internal.typeOf1 _ 
    = Data.Typeable.Internal.mkTyConApp 
     (Data.Typeable.Internal.mkTyCon 
      17188516606402618172## 4748486123618388125## "main" "Main" "DF") 
     [] 

instance Data.Typeable.Internal.Typeable1 Main.DF where 
    Data.Typeable.Internal.typeOf1 _ 
    = Data.Typeable.Internal.mkTyConApp 
     (Data.Typeable.Internal.mkTyCon 
      17188516606402618172## 4748486123618388125## "main" "Main" "DF") 
     [] 

所以這種類型的推導是不是真的做你想要它做的事情 - 這是獲得家庭爲Typeable1不是實例。但是,然後,可能你需要自instance (Typeable1 s, Typeable a) => Typeable (s a)內置。

data family DF a 
deriving instance Typeable1 DF 
data instance DF Int = DFInt deriving (Show) 
data instance DF Char = DFChar deriving (Show) 

data DFAll = forall a . Typeable a => DFAll (DF a) 

toDFA :: Typeable a => DF a -> DFAll 
toDFA = DFAll 

fromDFA :: Typeable a => DFAll -> Maybe (DF a) 
fromDFA (DFAll x) = cast x 

*Main> fromDFA (toDFA DFInt) :: Maybe (DF Int) 
Just DFInt 
+0

所以實例推導問題看起來像一個錯誤。關於你的答案,你究竟是爲什麼介紹存在的? –

+0

只是爲了證明你得到了一個正在運行的'cast'。 –

3

添加一個獨立派生Typeable1實例,如下面的代碼,已經解決了這個問題,但我沒有解釋爲什麼這會起作用,所以問題仍然存在。

data family DF a 
deriving instance Typeable1 DF 
data instance DF Int = DFInt deriving (Show) 
data instance DF Char = DFChar deriving (Show)