簡體   English   中英

Semigroup和Monoid實例中約束的差異

[英]Difference of constraints in Semigroup and Monoid instances

為什么Monoid實例需要(Ord a,ord b)約束,而Semigroup實例卻沒有?

這取決於Category.Constrained類還是使用GADT來定義數據類型?

{-# LANGUAGE GADTs, TypeFamilies, ConstraintKinds, StandaloneDeriving #-}

module Question3 where

import Control.Category.Constrained as CC
import Data.Set as S
import Data.Map as M

data RelationMS a b where
  IdRMS :: RelationMS a a
  RMS :: (Ord a, Ord b) => Map a (Set b) -> RelationMS a b 
deriving instance (Show a, Show b) => Show (RelationMS a b)

RMS mp2 `compRMS` RMS mp1
  | M.null mp2 || M.null mp1 = RMS M.empty
  | otherwise = RMS $ M.foldrWithKey 
        (\k s acc -> M.insert k (S.foldr (\x acc2 -> case M.lookup x mp2 of
                                                    Nothing -> acc2
                                                    Just s2 -> S.union s2 acc2
                                         ) S.empty s
                                ) acc
        ) M.empty mp1

instance Category RelationMS where
    type Object RelationMS o = Ord o
    id = IdRMS
    (.) = compRMS

instance Semigroup (RelationMS a b) where 
    RMS r1 <> RMS r2 = RMS $ M.foldrWithKey (\k s acc -> M.insertWith S.union k s acc) r1  r2 

instance (Ord a, Ord b) => Monoid (RelationMS a b) where
    mempty = RMS $ M.empty
    mappend = (<>)

這當然與類別實例無關。

Semigroup實例至少在概念上也需要Ord ,但是你已經將它打包在GADT中(除了在Id情況下,因為它是微不足道的,所以不需要它),所以沒有必要在實例中提到約束頭。

對於mempty但是,你沒有 RelationMS手頭價值,從中可以讀出(Ord a, Ord b)的約束。 恰恰相反:你需要提供這些約束,因為你現在正試圖結束這樣的GADT! 這就是為什么Monoid實例都需要在其頭部約束,但Semigroup一個沒有。

為什么Monoid實例需要(Ord a,ord b)約束,而Semigroup實例卻沒有?

嘗試刪除約束並讓GHC告訴您原因。

ac.hs:33:14: error:
    • No instance for (Ord a) arising from a use of ‘RMS’
      Possible fix:
        add (Ord a) to the context of the instance declaration
    • In the expression: RMS $ M.empty
      In an equation for ‘mempty’: mempty = RMS $ M.empty
      In the instance declaration for ‘Monoid (RelationMS a b)’
   |
33 |     mempty = RMS $ M.empty
   |

RMS需要Ord a嗎? 你說:

  RMS :: (Ord a, Ord b) => Map a (Set b) -> RelationMS a b

所以,是的。

暫無
暫無

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

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