簡體   English   中英

為什么GHC不能為Monoid派生實例?

[英]Why can't GHC derive instances for Monoid?

GHC有一些語言標志,例如DeriveFunctorDeriveDataTypeable等,它們可以為Haskell 98中允許的類型類之外的類型類生成派生實例的編譯器。這對像Functor這樣的東西特別有意義,其中該類的規則決定了明顯的,“自然的”派生實例。

那么Monoid為什么不呢? 對於具有單個數據構造函數的任何數據類型,似乎:

data T = MkT a b c ...

一個人可以機械地產生一個Monoid實例(原諒偽代碼):

instance (Monoid a, Monoid b, Monoid c, ...) => Monoid T where
  mempty =
    MkT mempty mempty mempty ...
  mappend (MkT a1 b1 c1 ...) (MkT a2 b2 c2 ...) =
    MkT (mappend a1 a2) (mappend b1 b2) (mappend c1 c2) ...

我知道派生提供了這個 ,但我的問題具體是GHC沒有的原因。

這是一個任意的決定,不能導出Monoid ,但幺半群也很一般,所以通常有很多方法可以使一個類型成為一個monoid。 這是一個例子:

data T = A | B | C deriving (Eq, Ord, Enum)

type Mon a = (a, a -> a -> a)

m1, m2, m3, m4 :: Mon T
m1 = (A, max)
m2 = (C, min)
m3 = (A, \ x y -> toEnum $ (fromEnum x + fromEnum y) `rem` 3)
m4 = (B, f4)
f4 A _ = A
f4 B x = x
f4 C _ = C

這顯示了使T成為monoid的四種合理方法( Mon包含單位和二元運算)。 第一個是采用最大值的幺半群,第二個采用最小值的幺半群,第三個來自模3算術的幺半群,第四個是用於Ordering類型的幺半群。 沒有什么比自然方式更突出。

你可以問Num和其他一些課程。 這將是無關緊要的:所有其他標准派生適用於具有多個構造函數的數據類型。

作為替代,您可以使用newtype派生newtype T = MkT (a,b,c) deriving Monoid

類似的擴展:您可以使空數據類型成為幾乎每個類型類的實例。

deriving子句始終是臨時和不方便的Haskell的一部分,因為它只適用於預定義的類。 添加更多臨時擴展會使語言復雜化。 相反,GHC最近獲得了對通用派生的支持。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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