Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 半群与幺半群实例中约束的差异_Haskell_Category Abstractions - Fatal编程技术网

Haskell 半群与幺半群实例中约束的差异

Haskell 半群与幺半群实例中约束的差异,haskell,category-abstractions,Haskell,Category Abstractions,为什么幺半群实例需要(Ord a,Ord b)约束而半群实例不需要 这取决于Category.Constrained类还是GADT用于定义数据类型 {-# LANGUAGE GADTs, TypeFamilies, ConstraintKinds, StandaloneDeriving #-} module Question3 where import Control.Category.Constrained as CC import Data.Set as S import Data.Ma

为什么幺半群实例需要(Ord a,Ord b)约束而半群实例不需要

这取决于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 = (<>)
{-#语言GADT、类型族、约束种类、独立派生}
模块问题3在哪里
导入控件.Category.Constrained为CC
导入数据。设置为S
导入数据。映射为M
数据关系a b,其中
IdRMS::关系a
RMS::(Ord a,Ord b)=>地图a(集合b)->关系a b
派生实例(Show a,Show b)=>Show(relations a b)
RMS mp2`compRMS`RMS mp1
|M.null mp2 | | M.null mp1=RMS M.empty
|否则=RMS$M.foldrWithKey
(\k s acc->M.insert k(s.foldr)(\x acc2->case M.lookup x mp2 of
无->acc2
只需s2->S.union s2 acc2
)空的
)行政协调会
)M.empty mp1
实例类别关系,其中
类型对象关系M o=Ord o
id=IdRMS
()=compms
实例半群(关系a b),其中
RMS r1 RMS r2=RMS$M.foldrWithKey(\k s acc->M.insertWith s.union k s acc)r1 r2
实例(Ord a,Ord b)=>幺半群(关系a b),其中
mempty=RMS$M.empty
mappend=()
为什么幺半群实例需要(Ord a,Ord b)约束而半群实例不需要

尝试移除约束并让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

所以,是的。

这当然与类别实例无关

半群
实例至少在概念上也需要
Ord
,但是您已经在GADT中打包了它(除了在
Id
情况下,它不需要,因为它很简单),因此不需要在实例头中提到约束


但是,对于
mempty
而言,您手头没有一个
RelationMS
值,您可以从中读取
(Ord a,Ord b)
约束。恰恰相反:您需要提供这些约束,因为您现在正试图结束这样一个GADT!这就是为什么
Monoid
实例需要头部约束,而
半群则不需要。

这是正确的,但只是故事的一半
()
也使用
RMS
,但在这一点上,我们不需要
Ord
约束。这是因为我们已经有了一个我们匹配的GADT模式。