2011-09-20 24 views
1

在瞭解有關Haskell的類型系統的更多信息時,我遇到了這個玩具問題。當我編譯以下代碼:使用數據中的數據時的函子錯誤:「無法構造無限類型」

data SingleData a = SingleData a Int String -- etc. 
data DataFail a = DataFail [SingleData a] 
instance Functor DataFail where 
    fmap f (DataFail xs) = DataFail (map f xs) 

我得到可怕的「時發生檢查:無法構造無限類型:B = SingleData b」的消息上FMAP的定義。奇怪的是,FMAP相同的定義將工作,如果它是實例聲明之外:

fmapWorks f (DataFail xs) = DataFail (map f xs) 

更奇怪的是,實施含半幺羣編譯和工作得很好:

instance Monoid (DataFail a) where 
    mempty = DataFail [] 
    mappend (DataFail xs) (DataFail ys) = DataFail (xs ++ ys) 

我認爲,這是不知何故

data DataSuccess a = DataSuccess [a] 
instance Functor DataSuccess where 
    fmap f (DataSuccess xs) = DataSuccess (map f xs) 

爲什麼Haskell的抱怨DataFail的FMAP功能,我能做些什麼來:使用SingleData DataFail內,因爲這個工作也很不錯的結果修理它?

+1

如果你看看'fmapWorks'的類型,你會發現它不是'fmap'所需的類型。 – augustss

回答

8

的「出現,請檢查」錯誤並不可怕......

的問題是提供給fmap功能。試試這個:

instance Functor SingleData where 
    fmap f (SingleData a i s) = SingleData (f a) i s 

instance Functor DataFail where 
    fmap f (DataFail sds) = DataFail $ map (fmap f) sds 

所以,實際的錯誤是你的map用法:類型不匹配。 Functor預計它的類型爲a -> b,但您使用的方式爲SingleData a -> SingleData b; SingleData的額外Functor實例允許您使用fmap將函數直接應用於其內部的值。

相關問題