2011-04-12 45 views
0

我最近將一個類型類別從約束MonadError GenError m推廣到更爲靈活的MonadError e m, CanContainGenError e約束。這對於使用已經具有ErrorT SomeError m的棧的相關單子變壓器很有用 - 我可以將GenError添加爲SomeError數據類型中新構造函數的元素。是否有「ContainsType」類?

我發現自己寫了一個硬編碼爲GenError的自定義CanContainGenError類,感到非常驚訝。是不是有一個共同的ContainedType類或一些這樣的? (我幾乎把它稱爲「亞型」,嘿嘿)

下面的任何東西CanContainTypeContainsType我剛剛做出的類?

class CanContainType cont orig where 
    toCont :: orig -> cont 
    fromCont :: cont -> Maybe orig 

class ContainsType orig sub where 
    toContainer :: orig -> cont 
    fromContainer :: cont -> orig 

凡實例例示如下:

-- edit fixed example instance to reflect what I want, sorry for the misleading code 
data IntOrFloatOrDouble= I Int | F Float | D Double 
instance CanContainType IntOrFloatOrDouble Int where 
    toCont = I 
    fromCont (I a) = Just a 
    fromCont _ = Nothing 

現在,我已經輸入了這一點,我意識到有可能是沒有建立一個,因爲我的要求授權MPTCs。不過,我對任何想法都感興趣。

+0

您的用於IntAndStuff的'toCont'不起作用。這也指出了爲什麼你的'toCont'和'toContainer'函數有點不好,我想。如果將值注入容器,則需要所有其他位的默認值。一般來說,我認爲這個解決方案有點太過分弱,所以想要/需要的人經常採用基於HList的解決方案。 – sclv 2011-04-13 16:33:26

+0

@sclv沒錯,那個例子很糟糕。在我的真實代碼中,我有'數據SomeError = PreExistinErr1 | PreExistinErr2 | IsGenError GenError',在實例中它只是'toCont = IsGenError'。這就是爲什麼我不需要默認位。看我的編輯。 – 2011-04-13 17:05:14

回答

1

有時這樣的事情出現在EDSL構建中,用於將Haskell的實例提取到EDSL。見例如http://www.galois.com/~dons/tmp/Type.hs

data IntegralType a where 
    TypeInt  :: IntegralDict Int  -> IntegralType Int 
    TypeInt8 :: IntegralDict Int8 -> IntegralType Int8 
    TypeInt16 :: IntegralDict Int16 -> IntegralType Int16 
    TypeInt32 :: IntegralDict Int32 -> IntegralType Int32 
    TypeInt64 :: IntegralDict Int64 -> IntegralType Int64 
    ... 

顯然沒有什麼標準。