{-# LANGUAGE FlexibleInstances #-}{-# LANGUAGE TypeFamilies #-}{-# LANGUAGE UndecidableInstances #-}{-# LANGUAGE GeneralizedNewtypeDeriving #-}{-# LANGUAGE DatatypeContexts #-}{-# LANGUAGE MultiParamTypeClasses #-}-- | These algebraic structures have sacrificed generality in favor of being easily used with the standard Haskell Prelude. The fact that monoids are not guaranteed to be semigroups makes this difficult.moduleHLearn.Algebra.Structures.Free.RegSG2GroupwhereimportHLearn.Algebra.Structures.GroupsimportHLearn.Algebra.Structures.ModulesimportControl.DeepSeq-- | Convert any regular semigroup into a group (and thus also a monoid) by adding a unique identity elementdata(RegularSemigroupsg)=>RegSG2Groupsg=SGNothing|SGJustsgderiving(Show,Read,Ord,Eq)instance(RegularSemigroupsg)=>Semigroup(RegSG2Groupsg)whereSGNothing<>m=mm<>SGNothing=m(SGJustsg1)<>(SGJustsg2)=SGJust$sg1<>sg2instance(RegularSemigroupsg)=>RegularSemigroup(RegSG2Groupsg)whereinverseSGNothing=SGNothinginverse(SGJustx)=SGJust$inversexinstance(RegularSemigroupsg)=>Monoid(RegSG2Groupsg)wheremempty=SGNothingmappend=(<>)instance(RegularSemigroupsg)=>Group(RegSG2Groupsg)instance(RegularSemigroupsg,NFDatasg)=>NFData(RegSG2Groupsg)wherernfSGNothing=()rnf(SGJustsg)=rnfsginstance(LeftOperatorrsg,RegularSemigroupsg)=>LeftOperatorr(RegSG2Groupsg)wherer.*(SGNothing)=SGNothingr.*(SGJustsg)=SGJust$r.*sginstance(RightOperatorrsg,RegularSemigroupsg)=>RightOperatorr(RegSG2Groupsg)where(SGNothing)*.r=SGNothing(SGJustsg)*.r=SGJust$sg*.r