haskell-jp / beginners #17 at 2021-07-17 09:35:36 +0900

SemiGroup,Monoidが定義されている状態でGroupを自分で定義してMonoidのインスタンスにしたいのですが<>はSemigroup,memptyはMonoidで定義されている時にインスタンス宣言を一つで済ませる方法はないのでしょうか?
instance Group Bool where
unit = False
plus = (||)
inv = (const False)

instance Ring Bool where
product = (&&)
unitpro = True

instance Field Bool where
invpro = (const True)
口頭で伺ったところ、 Group 型クラスなどは自分で定義したものだそうなので、 Group 型クラスを :point_down: のように書き換えてみると、重複が少なくて済むのではないでしょうか:
class Monoid a => Group a where
  inv :: a -> a
画面共有で確認しました。仰っていることを実現したい場合、元の Field 型クラスのメソッドとして unitから invpro まですべて定義しないとできませんね... どうしても一箇所にまとめたいのであれば例えば定義用のmoduleを分けるとして、
module BoolMethods where

unit :: Bool
unit = False

plus :: Bool -> Bool -> Bool
plus = (||)

...

invpro :: Bool -> Bool
invpro = const True

みたいな BoolMethods というモジュールを定義してから、
module BoolInstances where

import qualified BoolMethods as B

instance Group Bool where
  unit = B.unit
  ...

という書き方をするしかないですね...
あくまでもFieldのメソッドはFieldのメソッドであって、GroupやRingのメソッドではないので。
ありがとうございます
たとえば派生クラスの定義があるなら基底クラスの定義は自然に導出できるよ、という場合、以下の fmapDefaultfoldMapDefault ように普通の関数として提供しておいてインスタンス定義のときに使ってね、というパターンもあります
https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Traversable.html#v:foldMapDefault
ありがとうございます