繁体   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