[英]Constraints on a Haskell typeclass for the definition of a group
我想出了一個Group的類型類定義,但是我找到了一個實際上並不是一個組的反例類型。
這是類定義和一個實例,即組ℤ2:
class Group g where
iden :: g
op :: g -> g -> g
inv :: g -> g
data Z2T = Z0 | Z1
instance Group Z2T where
iden = Z0
Z0 `op` Z0 = Z0
Z0 `op` Z1 = Z1
Z1 `op` Z0 = Z1
Z1 `op` Z1 = Z0
inv Z0 = Z1
inv Z1 = Z0
但是, Group
那些類型簽名是必要的,但是對於一個真正成為一個組的類型來說還不夠,這里是我編譯的反例:
data NotAGroup = N0 | N1
instance Group NotAGroup where
iden = N0
N0 `op` N0 = N0
N1 `op` N0 = N0
N0 `op` N1 = N0
N1 `op` N1 = N0
inv N0 = N0
inv N1 = N0
如何將類型的足夠規則編碼為Haskell中的Group
類型類中的Group
?
你是對的,可以寫出違反集團法的Group
類型類的實例,因為實際上代碼中沒有任何內容實際說明它們。
對於Monad
類來說,這種情況也是如此,其中monadic法則不是以任何方式編寫或強制執行的。 您可以編寫一個非法的Monad
實例,因為您可以編寫一個非法的Group
實例。
這實際上是你在Haskell中可以獲得的最好的,至少不會過多地增加類型簽名的復雜性。 事實上,要表達類型中的組定律,您可能需要一種完全依賴類型的語言,而Haskell則不然。
在這種情況下,法律通常寫在評論中,可能表示為重寫規則,程序員通常具有足夠的紀律來尊重它們。
您無法執行此類法律,但您可以記錄這些法律。 例如, Monoid
類記錄了Monoid
任何實例應遵守的四個定律:
-- | The class of monoids (types with an associative binary operation that
-- has an identity). Instances should satisfy the following laws:
--
-- * @mappend mempty x = x@
--
-- * @mappend x mempty = x@
--
-- * @mappend x (mappend y z) = mappend (mappend x y) z@
--
-- * @mconcat = 'foldr' mappend mempty@
一個組只是一個具有額外逆操作的幺半群。 使您的Group
類成為Monoid
的子類; 那么你只需要記錄你的逆操作必須遵守的附加法則。
class Monoid g => Group g where
ginverse :: g -> g
-- ginv must obey the following laws
-- x `gappend` (ginverse x) == gempty
-- (ginverse x) `gappend` x == gempty
-- g-prefixed synonym for mappend
gappend :: Group g => g -> g -> g
gappend = mappend
-- g-prefixed synonym for mempty
gempty :: Group g => g
gempty = mempty
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.