[英]Can GHC derive Functor and Applicative instances for a monad transformer?
[英]Why can't GHC derive instances for Monoid?
GHC有一些語言標志,例如DeriveFunctor
, DeriveDataTypeable
等,它們可以為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) ...
這是一個任意的決定,不能導出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.