I'm writing a program for representation of finite groups and simple operations on their elements. I wrote most of the functionality which I need, for example inverse elements, generators, checking if subset is subgroup etc.
Unfortunately all my functions need identity element, set and operation. I want to define the appropriate instance of the class and use it instead of this trio. And here begins my problem, I don't quite know how to go about it and all I can find on the internet contains only examples of definitions, without usage examples.
Eventually I would like to work with groups Sn
, so far I've tested my code on (Zn +
).
I wrote this:
data Z2 = Elm Int deriving (Show, Eq)
z2 :: Int -> Z2
z2 a = Elm (a `mod` 2)
class FiniteGroup a where
identity :: a
op :: a -> a -> a -- operation
set :: [a]
instance FiniteGroup Z2 where
identity = (Elm 0)
op (Elm x) (Elm y) = z2 (x+y)
set = [(Elm 0), (Elm 1)]
And it works fine for the function op
, for example:
*Main> (Elm 1) `op` (Elm 0)
Elm 1
Unfortunately, I cant use identity
and set
. How do I use it?
I also can't figure out how to refactor an existing function to use my type class.
For example I have this:
cyclicGenerators :: (Eq a) => a -> [a] -> (a -> a -> a) -> [a]
and it works fine, but I want to have something like this:
cyclicGenerators :: (Eq a) => FiniteGroup a -> [a]