0
votes

The type signature from Monoid mempty function is:

*Exercises Data.Monoid> :t mempty
mempty :: Monoid a => a

When I look at the type signature for function(->) type on typeclass Monoid for mempty function it becomes to:

mempty :: Monoid b => a -> b

Because a will be replace through a -> b.

mempty :: Monoid a => a
mempty :: a -> b

I did not mention that b has to be a Monoid, otherwise the mappend function would not work.

Now I have following data type

newtype Combine a b = 
  Combine { unCombine :: a -> b }

instance (Semigroup b) 
  => Semigroup (Combine a b) where 
  Combine {unCombine=f} <> Combine {unCombine=g} = Combine (f <> g)

instance (Semigroup b, Monoid b)
  => Monoid (Combine a b) where
  mempty = Combine mempty
  mappend = (<>)

How the mempty function signature looks like for Combine?

So I am going to do exactly the same way as above:

The mempty declaration:

mempty :: Monoid a => a

a will be replace through Combine, then it becomes to:

mempty :: Combine a b

?

1
You forgot the constraint Monoid b. mempty :: Monoid b => Combine a b. Combine a b is just a wrapper for a -> b. So it is basically Monoid b => a -> b again. The part before the => is the typeclass, which is replaced by the corresponding type dictionary at compile time. It tells the compiler how to produce a value of type b. - user6445533

1 Answers

3
votes

Why not ask ghci? You have mempty = Combine mempty, so:

> :t Combine mempty
Combine mempty :: Monoid b => Combine a b

Therefore the type of mempty for Combine must be at least as specific as that.