What is the mempty datatype?

I have the following datatype with monoid and semigroup instance:

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 = (<>)

      

I want to customize it, what is the value mempty

for the function (->)

?

I tried for example:

*Exercises Data.Monoid> mempty :: (-> Integer Bool)
<interactive>:21:15: error: parse error on input `Integer'

      

What does the implementation look like mempty

in monoid

?

I looked at the source of the hack:

instance Monoid b => Monoid (a -> b) where
        mempty _ = mempty
        mappend f g x = f x `mappend` g x

      

and cannot find an implementation mempty

.

Perhaps to clarify what I mean, consider the following example:

*Exercises Data.Monoid> mempty :: (Product Integer)
Product {getProduct = 1}

      

The mempty element Product Integer

is Product {getProduct = 1}

.

+3


source to share


1 answer


  • A type constructor is (->)

    not a type constant (no type values (->)

    ) and therefore cannot have a monoid instance.
  • If the type b

    has a monoid instance, the type constant a -> b

    (or (->) a b

    ) has a monoid instance and mempty

    gives a function that ignores its inputs and returns mempty

    of b

    as a value.

If you look

instance Monoid b => Monoid (a -> b) where
    mempty _ = mempty
    mappend f g x = f x `mappend` g x
      

the line implements this.mempty _ = mempty

What is the type mempty

for a -> b

? This a -> b

is because it mempty

must be a value of the type a -> b

. So



mempty _ = mempty

tells us what mempty

for a -> b

is a function that discards its input and returns , a value of type . The two occurrences of the name in this definition refer to different functions / values. mempty

b

mempty

Apply some specific examples:

  • You tried

    mempty :: (-> Integer Bool)
    
          

    which is syntactically incorrect. You wanted to try

    mempty :: (->) Integer Bool
    
          

    which gives a new error

    <interactive>:5:1: error:
       β€’ No instance for (Monoid Bool) arising from a use of β€˜mempty’
       β€’ In the expression: mempty :: (->) Integer Bool
         In an equation for β€˜it’: it = mempty :: (->) Integer Bool
    
          

    since it Bool

    does not have a monoid instance.

  • You tried

    mempty :: (Product Integer)
    
          

    which worked and gave Product {getProduct = 1}

    as meaning. This tells you it Product Integer

    has a monoid instance. Therefore, we could try to have Product Integer

    both type in . b

    a -> b

  • Now try

    > let f = mempty :: a -> Product Integer
    > f 'x'
    Product {getProduct = 1}
    
          

    In this example, it mempty

    refers to some value of the type a -> Product Integer

    and is therefore a function. So the type variable t

    from mempty :: (Monoid t) => t

    in this case is of the type a -> Product Integer

    .

+6


source







All Articles