警衛

2017-07-11 87 views
0

哈斯克爾替代類和虛函數可以說我有以下ADT,警衛

data Properties a = Property String a 
    deriving (Show,Eq) 

我已經做了以下情況吧,

instance Functor Properties where 
    fmap f (Property name prop) = Property name (f prop) 
-- 
instance Applicative (Properties) where 
    pure a = Property "" a 
    (Property _ f) <*> p = fmap f p 

instance Monad (Properties) where 
    return a = Property "" a 
    (Property name prop) >>= f = (f prop) 

到目前爲止好。讓我們看看我們可以迄今爲止做,

pColors = Property "Color" ["Blue", "Red", "White"] 
pNationality = Property "Nationality" ["Italian", "Norwegian", "Spanish"] 

answers = do 
    color <- fmap permutations pColors 
    nation <- fmap permutations pNationality 
    return $ zip color nation 

給人,

*Main> answers 
Property "" [(["Blue","Red","White"],["Italian","Norwegian","Spanish"]),(["Red","Blue","White"],["Norwegian","Italian","Spanish"]),(["White","Red","Blue"],["Spanish","Norwegian","Italian"]),(["Red","White","Blue"],["Norwegian","Spanish","Italian"]),(["White","Blue","Red"],["Spanish","Italian","Norwegian"]),(["Blue","White","Red"],["Italian","Spanish","Norwegian"])] 

所以fmap和預期的單子綁定都在工作。現在我想使用alternative中的guard函數。基本上我想根據一些謂詞修剪pColorspNationality。所以我嘗試定義,

instance Alternative (Properties) where 
    empty = Property "" [] 

但是,這給了我一個錯誤,我認爲(請糾正我,如果我錯了),這是因爲Haskell是解釋[]a不同。但我認爲a可能是任何東西,而[]是其中之一,所以問題是什麼?

+0

如果您使用'{ - #LANGUAGE GeneralizedNewtypeDivingiving# - }' – 4castle

+0

您可以執行'newtype屬性a =屬性(String,a)派生(Show,Eq,Functor,Applicative,Monad)'上面的ADT?如果我編寫'newtype Property a = String a derivation(Show,Eq,Functor,Applicative,Monad)',它自己假設(避免多個'Property'的聲明)'給出一個錯誤,Functor不能派生出來並且不得不使用'DerivedFunctor'。 – ITA

+0

並加入'DerivedFunctor'則誤差變, '不能讓「應用型住宅」 (甚至狡猾GeneralizedNewtypeDeriving)的衍生實例: 不能ETA-減少表示類型enough' – ITA

回答

4

但我認爲a可以是任何東西和[]是任何一個,所以有什麼問題?

不是說a可以是任何東西,但是a必須能夠是任何東西。這是如果用戶寫入x :: Property [a]; x = empty,那必須被允許,但是x :: Property Int; x = empty也必須被允許。你的定義只允許前者,所以這是不正確的。

沒有辦法定義有效emptyProperty類型,除非你讓它產生錯誤(如empty = Property "" undefined)或改變的Property定義添加一個案例的空屬性。

+0

謝謝,有沒有一個'Listable'類的類約束,我可以給'a'? – ITA

+1

@IvanAbraham有一個['IsList'](https://hackage.haskell.org/package/base-4.9.0.0/docs/GHC-Exts.html#t:IsList)typeclass,但是沒有辦法添加' IsList a =>'作爲'empty'的約束。 'Alternative'要求*任何*類型都可以用作'a'中的'a'。 – 4castle

+0

@ 4Castle它是否與'ConstraintKinds'一起使用?我的目標是爲dataType定義'Alternative'。 '未定義'技巧與'空'一起工作(稍後可能會有所改變)。但對於'<|>'我只想在元組的第二個元素上做'++'(就像在你以前的評論中一樣)。 – ITA