1
votes

I'm new to haskell and I've tried to make my own typeclass here:

class Group g where
    makeGroup :: g -> g -> [g]

instance Group Int where
    makeGroup size offset = [ x `mod` size | x <- [1 + offset, size + offset]]

myTest :: (Group g) => Int -> Int -> [g]
myTest x y = makeGroup x y

Could someone tell me where I went wrong?

New problem

The type signature myTest :: (Group g) => g -> g -> [g] compiles but throws this error

<interactive>:30:1: No instance for (Group g0) arising from a use of ‘it’ The type variable ‘g0’ is ambiguous Note: there is a potential instance available: instance Group Int -- Defined at ex.hs:4:10 In the first argument of ‘print’, namely ‘it’ In a stmt of an interactive GHCi command: print it

What does this stem from?

1
To print something, it must be an instance of the Show typeclass.Jeff Ames
@JeffAmes so I should make group part of the show type class? And if so how would I do that?m0meni
I think you'd want class (Show g) => Group g where ...Jeff Ames

1 Answers

6
votes

This is your class definition:

class Group g where
    makeGroup :: g -> g -> [g]

This means that in any use of makeGroup, all three occurrences of the type variable g must be instantiated to the same type. But in your myTest function's type signature, you're indirectly saying that the first two occurrences are Ints but the third one could be any type g (caller's choice!) that satisfies the Group constraint:

myTest :: (Group g) => Int -> Int -> [g]
myTest x y = makeGroup x y

EDIT: Well, to make this much clearer, I should add that when we say that g could be "any type," more precisely this means that it could be any type that myTest's caller chooses. This is the way generic types work: the function myTest is like a template that the caller can specialize by choosing what type they would like g to be.

The notation is odd, but (g ~ Int) in the error is a type equality constraint: Haskell is telling you that, given the declarations that you've provided elsewhere, in myTest's signature g's type must be the same as Int, but you've asserted that it could be any type g as long as that type implements Group. That assertion is not compatible with what you've said elsewhere in the code.