簡體   English   中英

Haskell類型類的約束,用於定義組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM