newtype v. data for Monoid Wrappers? [duplicate] - haskell

When looking at Data.Monoid, I see there are various newtype wrappers, such as All, Sum, or Product, which encode various kinds of monoids. However, when trying to use those wrappers, I can't help but wonder what's the benefit over using their non-Data.Monoid counterparts. For instance, compare the rather cumbersome summation
print $ getSum $ mconcat [ Sum 33, Sum 2, Sum 55 ]
vs. the more succinct idiomatic variant
print $ sum [ 33, 2, 55 ]
But what's the point? Is there any practical value having all those newtype wrappers? Are there more convincing examples of Monoid newtype wrapper usage than the one above?

Monoid newtypes: A zero space no-op to tell the compiler what to do
Monoids are great to wrap an existing data type in a new type to tell the compiler what operation you want to do.
Since they're newtypes, they don't take any additional space and applying Sum or getSum is a no-op.
Example: Monoids in Foldable
There's more than one way to generalise foldr (see this very good question for the most general fold, and this question if you like the tree examples below but want to see a most general fold for trees).
One useful way (not the most general way, but definitely useful) is to say something's foldable if you can combine its elements into one with a binary operation and a start/identity element. That's the point of the Foldable typeclass.
Instead of explicitly passing in a binary operation and start element, Foldable just asks that the element data type is an instance of Monoid.
At first sight this seems frustrating because we can only use one binary operation per data type - but should we use (+) and 0 for Int and take sums but never products, or the other way round? Perhaps should we use ((+),0) for Int and (*),1 for Integer and convert when we want the other operation? Wouldn't that waste a lot of precious processor cycles?
Monoids to the rescue
All we need to do is tag with Sum if we want to add, tag with Product if we want to multiply, or even tag with a hand-rolled newtype if we want to do something different.
Let's fold some trees! We'll need
fold :: (Foldable t, Monoid m) => t m -> m
-- if the element type is already a monoid
foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
-- if you need to map a function onto the elements first
The DeriveFunctor and DeriveFoldable extensions ({-# LANGUAGE DeriveFunctor, DeriveFoldable #-}) are great if you want to map over and fold up your own ADT without writing the tedious instances yourself.
import Data.Monoid
import Data.Foldable
import Data.Tree
import Data.Tree.Pretty -- from the pretty-tree package
see :: Show a => Tree a -> IO ()
see = putStrLn.drawVerticalTree.fmap show
numTree :: Num a => Tree a
numTree = Node 3 [Node 2 [],Node 5 [Node 2 [],Node 1 []],Node 10 []]
familyTree = Node " Grandmama " [Node " Uncle Fester " [Node " Cousin It " []],
Node " Gomez - Morticia " [Node " Wednesday " [],
Node " Pugsley " []]]
Example usage
Strings are already a monoid using (++) and [], so we can fold with them, but numbers aren't, so we'll tag them using foldMap.
ghci> see familyTree
" Grandmama "
|
----------------------
/ \
" Uncle Fester " " Gomez - Morticia "
| |
" Cousin It " -------------
/ \
" Wednesday " " Pugsley "
ghci> fold familyTree
" Grandmama Uncle Fester Cousin It Gomez - Morticia Wednesday Pugsley "
ghci> see numTree
3
|
--------
/ | \
2 5 10
|
--
/ \
2 1
ghci> getSum $ foldMap Sum numTree
23
ghci> getProduct $ foldMap Product numTree
600
ghci> getAll $ foldMap (All.(<= 10)) numTree
True
ghci> getAny $ foldMap (Any.(> 50)) numTree
False
Roll your own Monoid
But what if we wanted to find the maximum element? We can define our own monoids. I'm not sure why Max (and Min) aren't in. Maybe it's because no-one likes thinking about Int being bounded or they just don't like an identity element that's based on an implementation detail. In any case here it is:
newtype Max a = Max {getMax :: a}
instance (Ord a,Bounded a) => Monoid (Max a) where
mempty = Max minBound
mappend (Max a) (Max b) = Max $ if a >= b then a else b
ghci> getMax $ foldMap Max numTree :: Int -- Int to get Bounded instance
10
Conclusion
We can use newtype Monoid wrappers to tell the compiler which way to combine things in pairs.
The tags do nothing, but show what combining function to use.
It's like passing the functions in as an implicit parameter rather than an explicit one (because that's kind of what a type class does anyway).

How about in an instance like this:
myData :: [(Sum Integer, Product Double)]
myData = zip (map Sum [1..100]) (map Product [0.01,0.02..])
main = print $ mconcat myData
Or without the newtype wrapper and the Monoid instance:
myData :: [(Integer, Double)]
myData = zip [1..100] [0.01,0.02..]
main = print $ foldr (\(i, d) (accI, accD) -> (i + accI, d * accD)) (0, 1) myData
This is due to the fact that (Monoid a, Monoid b) => Monoid (a, b). Now, what if you had custom data types and you wanted to fold over a tuple of these values applying a binary operation? You could simply write a newtype wrapper and make it an instance of Monoid with that operation, construct your list of tuples, then just use mconcat to fold across them. There are many other functions that work on Monoids as well, not just mconcat, so there are certainly a myriad of applications.
You could also look at the First and Last newtype wrappers for Maybe a, I can think of many uses for those. The Endo wrapper is nice if you need to compose a lot of functions, the Any and All wrappers are good for working with booleans.

Suppose you are working in the Writer monad and you want to store the sum of everything you tell. In that case you would need the newtype wrapper.
You would also need the newtype to use functions like foldMap that have a Monoid constraint.
The ala and alaf combinators from Control.Lens.Wrapped in the lens package can make working with these newtypes more pleasant. From the documentation:
>>> alaf Sum foldMap length ["hello","world"]
10
>>> ala Sum foldMap [1,2,3,4]
10

Sometimes you just end up needing a particular Monoid to fill a type constraint. One place that shows up sometimes is that Const has an Applicative instance iff it stores a Monoid.
instance Monoid m => Applicative (Const m) where
pure _ = Const mempty
Const a <*> Const b = Const (a <> b)
That's obviously a bit bizarre, but sometimes it's what you need. The best example I know is in lens where you end up with types like
type Traversal s a = forall f . Applicative f => (a -> f a) -> (s -> f s)
If you specialize f to something like Const First using the Monoid newtype First
newtype First a = First { getFirst :: Maybe a }
-- Retains the first, leftmost 'Just'
instance Monoid (First a) where
mempty = First Nothing
mappend (First Nothing) (First Nothing) = First Nothing
mappend (First (Just x)) _ = First (Just x)
then we can interpret that type
(a -> Const (First a) a) -> (s -> Const (First a) s)
as scanning through s and picking up the first a inside of it.
So, while that's a really specific answer the broad response is that it's sometimes useful to be able to talk about a bunch of different default Monoid behaviors. Somebody had to write all the obvious Monoid behaviors, anyway, and they might as well be put in Data.Monoid.

The basic idea, I think, is that you can have something like
reduce = foldl (<>) mempty
and it'll work for any list of those wrapped things.

Related

What is the main difference between Free Monoid and Monoid?

Looks like I have a pretty clear understanding what a Monoid is in Haskell, but last time I heard about something called a free monoid.
What is a free monoid and how does it relate to a monoid?
Can you provide an example in Haskell?
As you already know, a monoid is a set with an element e and an operation <> satisfying
e <> x = x <> e = x (identity)
(x<>y)<>z = x<>(y<>z) (associativity)
Now, a free monoid, intuitively, is a monoid which satisfies only those equations above, and, obviously, all their consequences.
For instance, the Haskell list monoid ([a], [], (++)) is free.
By contrast, the Haskell sum monoid (Sum Int, Sum 0, \(Sum x) (Sum y) -> Sum (x+y)) is not free, since it also satisfies additional equations. For instance, it's commutative
x<>y = y<>x
and this does not follow from the first two equations.
Note that it can be proved, in maths, that all the free monoids are isomorphic to the list monoid [a]. So, "free monoid" in programming is only a fancy term for any data structure which 1) can be converted to a list, and back, with no loss of information, and 2) vice versa, a list can be converted to it, and back, with no loss of information.
In Haskell, you can mentally substitute "free monoid" with "list-like type".
In a programming context, I usually translate free monoid to [a]. In his excellent series of articles about category theory for programmers, Bartosz Milewski describes free monoids in Haskell as the list monoid (assuming one ignores some problems with infinite lists).
The identity element is the empty list, and the binary operation is list concatenation:
Prelude Data.Monoid> mempty :: [Int]
[]
Prelude Data.Monoid> [1..3] <> [7..10]
[1,2,3,7,8,9,10]
Intuitively, I think of this monoid to be 'free' because it a monoid that you can always apply, regardless of the type of value you want to work with (just like the free monad is a monad you can always create from any functor).
Additionally, when more than one monoid exists for a type, the free monoid defers the decision on which specific monoid to use. For example, for integers, infinitely many monoids exist, but the most common are addition and multiplication.
If you have two (or more integers), and you know that you may want to aggregate them, but you haven't yet decided which type of aggregation you want to apply, you can instead 'aggregate' them using the free monoid - practically, this means putting them in a list:
Prelude Data.Monoid> [3,7]
[3,7]
If you later decide that you want to add them together, then that's possible:
Prelude Data.Monoid> getSum $ mconcat $ Sum <$> [3,7]
10
If, instead, you wish to multiply them, you can do that as well:
Prelude Data.Monoid> getProduct $ mconcat $ Product <$> [3,7]
21
In these two examples, I've deliberately chosen to elevate each number to a type (Sum, Product) that embodies a more specific monoid, and then use mconcat to perform the aggregation.
For addition and multiplication, there are more succinct ways to do this, but I did it that way to illustrate how you can use a more specific monoid to interpret the free monoid.
A free monoid is a specific type of monoid. Specifically, it’s the monoid you get by taking some fixed set of elements as characters and then forming all possible strings from those elements. Those strings, with the underlying operation being string concatenation, form a monoid, and that monoid is called the free monoid.
A monoid (M,•,1) is a mathematical structure such that:
M is a set
1 is a member of M
• : M * M -> M
a•1 = a = 1•a
Given elements a, b and c in M, we have a•(b•c) = (a•b)•c.
A free monoid on a set M is a monoid (M',•,0) and function e : M -> M' such that, for any monoid (N,*,1), given a (set) map f : M -> N we can extend this to a monoid morphism f' : (M',•,0) -> (N,*,1), i.e
f a = f' (e a)
f' 0 = 1
f' (a•b) = (f' a) • (f' b)
In other words, it is a monoid that does nothing special.
An example monoid is the integers with the operation being addition and the identity being 0. Another monoid is sequences of integers with the operation being concatenation and the identity being the empty sequence. Now the integers under addition is not a free monoid on the integers. Consider the map into sequences of integers taking n to (n). Then for this to be free we would need to extend this to a map taking n + m to (n,m), i.e. it must take 0 to (0) and to (0,0) and to (0,0,0) and so on.
On the other hand if we try to look at sequences of integers as a free monoid on the integers, we see that it seems to work in this case. The extension of the map into the integers with addition is one that takes the sum of a sequence (with the sum of () being 0).
So what is the free monoid on a set S? Well one thing we could try is just arbitrary binary trees of S. In a Haskell type this would look like:
data T a = Unit | Single a | Conc (T a) (T a)
And it would have an identity of Unit, e = Single and (•) = Conc.
And we can write a function to show how it is free:
-- here the second argument represents a monoid structure on b
free :: (a -> b) -> (b -> b -> b, b) -> T a -> b
free f ((*),zero) = f' where
f' (Single a) = f a
f' Unit = zero
f' (Conc a b) = f' a * f' b
It should be quite obvious that this satisfies the required laws for a free monoid on a. Except for one: T a is not a monoid because it does not quite satisfy laws 4 or 5.
So now we should ask if we can make this into a simpler free monoid, ie one that is an actual monoid. The answer is yes. One way is to observe that Conc Unit a and Conc a Unit and Single a should be the same. So let’s make the first two types unrepresentable:
data TInner a = Single a | Conc (TInner a) (TInner a)
data T a = Unit | Inner (TInner a)
A second observation we can make is that there should be no difference between Conc (Conc a b) c and Conc a (Conc b c). This is due to law 5 above. We can then flatten our tree:
data TInner a = Single a | Conc (a,TInner a)
data T a = Unit | Inner (TInner a)
The strange construction with Conc forces us to only have a single way to represent Single a and Unit. But we see we can merge these all together: change the definition of Conc to Conc [a] and then we can change Single x to Conc [x], and Unit to Conc [] so we have:
data T a = Conc [a]
Or we can just write:
type T a = [a]
And the operations are:
unit = []
e a = [a]
(•) = append
free f ((*),zero) = f' where
f' [] = zero
f' (x:xs) = f x * f' xs
So in Haskell, the list type is called the free monoid.

Can you determine the min or max of a list using only the list monad?

Trying to understand the relation between Monad and Foldable. I am aware that that part of the value of the Monad, Applicative and Functor typeclasses is their ability to lift functions over structure, but what if I wanted to generate a summary value (e.g. min or max) for the values contained in a Monad?
This would be impossible without an accumulator right (like in foldable)? And to have an accumulator you have to inject or destroy structure?
min :: Ord a => a -> a -> a
foldMin :: (Foldable t, Ord a) => t a -> Maybe a
foldMin t = foldr go Nothing t
where
go x Nothing = Just x
go x (Just y) = Just (min x y)
Here, the Nothing value is the accumulator. So it would not be possible to do an operation that produces a summary value like this within the confines of a do block?
I'm not entirely sure I understand the question, so forgive me if this isn't a useful answer, but as I understand it, the core of the question is this:
So it would not be possible to do an operation that produces a summary value like this within the confines of a do block?
Correct, that would not be possible. Haskell's do notation is syntactic sugar over Monad, so basically syntactic sugar over >>= and return.
return, as you know, doesn't let you 'access' the contents of the Monad, so the only access to the contents you have is via >>=, and in the case of the list monad, for instance, that only gives you one value at a time.
Notice that Foldable doesn't even require that the data container is a Functor (much less a Monad). Famously, Set isn't a Functor instance, but it is a Foldable instance.
You can, for example, find the minimum value in a set:
Prelude Data.Foldable Set> foldr (\x -> Just . maybe x (min x)) Nothing $ Set.fromList [42, 1337, 90125, 2112]
Just 42
The contrived and inefficient code below is the closest I can get to "using only the list monad". This is probably not what the OP is looking for, but here it is.
I also exploit head (which you can replace with listToMaybe, if we want totality), and null. I also use empty (which you can replace with []).
The code works by non deterministically picking an element m and then checking that no greater elements exist. This has a quadratic complexity.
import Control.Applicative
maximum :: Ord a => [a] -> a
maximum xs = head maxima
where
isMax m = null $ do
x <- xs
if x > m
then return x
else empty
maxima = do
m <- xs -- non deterministically pick a maximum
if isMax m
then return m
else empty
I'm also not sure, what the actual question ist, but the need for an accumulator can be hidden with a Monoid instance. Then - for your minimum example - you can use use foldMap from Data.Foldable to map and merge all values of your Foldable. E.g.:
data Min a = Min { getMin :: Maybe a } deriving Show
instance Ord a => Monoid (Min a) where
mempty = Min Nothing
mappend a (Min Nothing) = a
mappend (Min Nothing) b = b
mappend (Min (Just a)) (Min (Just b)) = Min (Just (min a b))
foldMin :: (Foldable t, Ord a) => t a -> Maybe a
foldMin = getMin . foldMap (Min . Just)

How to "iterate" over a function whose type changes among iteration but the formal definition is the same

I have just started learning Haskell and I come across the following problem. I try to "iterate" the function \x->[x]. I expect to get the result [[8]] by
foldr1 (.) (replicate 2 (\x->[x])) $ (8 :: Int)
This does not work, and gives the following error message:
Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [a -> a]
Actual type: [a -> [a]]
I can understand why it doesn't work. It is because that foldr1 has type signature foldr1 :: Foldable t => (a -> a -> a) -> a -> t a -> a, and takes a -> a -> a as the type signature of its first parameter, not a -> a -> b
Neither does this, for the same reason:
((!! 2) $ iterate (\x->[x]) .) id) (8 :: Int)
However, this works:
(\x->[x]) $ (\x->[x]) $ (8 :: Int)
and I understand that the first (\x->[x]) and the second one are of different type (namely [Int]->[[Int]] and Int->[Int]), although formally they look the same.
Now say that I need to change the 2 to a large number, say 100.
My question is, is there a way to construct such a list? Do I have to resort to meta-programming techniques such as Template Haskell? If I have to resort to meta-programming, how can I do it?
As a side node, I have also tried to construct the string representation of such a list and read it. Although the string is much easier to construct, I don't know how to read such a string. For example,
read "[[[[[8]]]]]" :: ??
I don't know how to construct the ?? part when the number of nested layers is not known a priori. The only way I can think of is resorting to meta-programming.
The question above may not seem interesting enough, and I have a "real-life" case. Consider the following function:
natSucc x = [Left x,Right [x]]
This is the succ function used in the formal definition of natural numbers. Again, I cannot simply foldr1-replicate or !!-iterate it.
Any help will be appreciated. Suggestions on code styles are also welcome.
Edit:
After viewing the 3 answers given so far (again, thank you all very much for your time and efforts) I realized this is a more general problem that is not limited to lists. A similar type of problem can be composed for each valid type of functor (what if I want to get Just Just Just 8, although that may not make much sense on its own?).
You'll certainly agree that 2 :: Int and 4 :: Int have the same type. Because Haskell is not dependently typed†, that means foldr1 (.) (replicate 2 (\x->[x])) (8 :: Int) and foldr1 (.) (replicate 4 (\x->[x])) (8 :: Int) must have the same type, in contradiction with your idea that the former should give [[8]] :: [[Int]] and the latter [[[[8]]]] :: [[[[Int]]]]. In particular, it should be possible to put both of these expressions in a single list (Haskell lists need to have the same type for all their elements). But this just doesn't work.
The point is that you don't really want a Haskell list type: you want to be able to have different-depth branches in a single structure. Well, you can have that, and it doesn't require any clever type system hacks – we just need to be clear that this is not a list, but a tree. Something like this:
data Tree a = Leaf a | Rose [Tree a]
Then you can do
Prelude> foldr1 (.) (replicate 2 (\x->Rose [x])) $ Leaf (8 :: Int)
Rose [Rose [Leaf 8]]
Prelude> foldr1 (.) (replicate 4 (\x->Rose [x])) $ Leaf (8 :: Int)
Rose [Rose [Rose [Rose [Leaf 8]]]]
†Actually, modern GHC Haskell has quite a bunch of dependently-typed features (see DaniDiaz' answer), but these are still quite clearly separated from the value-level language.
I'd like to propose a very simple alternative which doesn't require any extensions or trickery: don't use different types.
Here is a type which can hold lists with any number of nestings, provided you say how many up front:
data NestList a = Zero a | Succ (NestList [a]) deriving Show
instance Functor NestList where
fmap f (Zero a) = Zero (f a)
fmap f (Succ as) = Succ (fmap (map f) as)
A value of this type is a church numeral indicating how many layers of nesting there are, followed by a value with that many layers of nesting; for example,
Succ (Succ (Zero [['a']])) :: NestList Char
It's now easy-cheesy to write your \x -> [x] iteration; since we want one more layer of nesting, we add one Succ.
> iterate (\x -> Succ (fmap (:[]) x)) (Zero 8) !! 5
Succ (Succ (Succ (Succ (Succ (Zero [[[[[8]]]]])))))
Your proposal for how to implement natural numbers can be modified similarly to use a simple recursive type. But the standard way is even cleaner: just take the above NestList and drop all the arguments.
data Nat = Zero | Succ Nat
This problem indeed requires somewhat advanced type-level programming.
I followed #chi's suggestion in the comments, and searched for a library that provided inductive type-level naturals with their corresponding singletons. I found the fin library, which is used in the answer.
The usual extensions for type-level trickery:
{-# language DataKinds, PolyKinds, KindSignatures, ScopedTypeVariables, TypeFamilies #-}
Here's a type family that maps a type-level natural and an element type to the type of the corresponding nested list:
import Data.Type.Nat
type family Nested (n::Nat) a where
Nested Z a = [a]
Nested (S n) a = [Nested n a]
For example, we can test from ghci that
*Main> :kind! Nested Nat3 Int
Nested Nat3 Int :: *
= [[[[Int]]]]
(Nat3 is a convenient alias defined in Data.Type.Nat.)
And here's a newtype that wraps the function we want to construct. It uses the type family to express the level of nesting
newtype Iterate (n::Nat) a = Iterate { runIterate :: (a -> [a]) -> a -> Nested n a }
The fin library provides a really nifty induction1 function that lets us compute a result by induction on Nat. We can use it to compute the Iterate that corresponds to every Nat. The Nat is passed implicitly, as a constraint:
iterate' :: forall n a. SNatI n => Iterate (n::Nat) a
iterate' =
let step :: forall m. SNatI m => Iterate m a -> Iterate (S m) a
step (Iterate recN) = Iterate (\f a -> [recN f a])
in induction1 (Iterate id) step
Testing the function in ghci (using -XTypeApplications to supply the Nat):
*Main> runIterate (iterate' #Nat3) pure True
[[[[True]]]]

Choosing the non-empty Monoid

I need a function which will choose a non-empty monoid. For a list this will mean the following behaviour:
> [1] `mor` []
[1]
> [1] `mor` [2]
[1]
> [] `mor` [2]
[2]
Now, I've actually implemented it but am wondering wether there exists some standard alternative, because it seems to be a kind of a common case. Unfortunately Hoogle doesn't help.
Here's my implementation:
mor :: (Eq a, Monoid a) => a -> a -> a
mor a b = if a /= mempty then a else b
If your lists contain at most one element, they're isomorphic to Maybe, and for that there's the "first non empty" monoid: First from Data.Monoid. It's a wrapper around Maybe a values, and mappend returns the first Just value:
import Data.Monoid
main = do
print $ (First $ Just 'a') <> (First $ Just 'b')
print $ (First $ Just 'a') <> (First Nothing)
print $ (First Nothing) <> (First $ Just 'b')
print $ (First Nothing) <> (First Nothing :: First Char)
==> Output:
First {getFirst = Just 'a'}
First {getFirst = Just 'a'}
First {getFirst = Just 'b'}
First {getFirst = Nothing}
Conversion [a] -> Maybe a is achieved using Data.Maybe.listToMaybe.
On a side note: this one does not constrain the typeclass of the wrapped type; in your question, you need an Eq instance to compare for equality with mempty. This comes at the cost of having the Maybe type, of course.
[This is really a long comment rather than an answer]
In my comment, when I said "monoidal things have no notion of introspection" - I meant that you can't perform analysis (pattern matching, equality, <, >, etc.) on monoids. This is obvious of course - the API of Monoids is only unit (mempty) and an operation mappend (more abstractly <>) that takes two monodial things and returns one. The definition of mappend for a type is free to use case analysis, but afterwards all you can do with monoidal things is use the Monoid API.
It's something of a folklore in the Haskell community to avoid inventing things, prefering instead to use objects from mathematics and computer science (including functional programming history). Combining Eq (which needs analysis of is arguments) and Monoid introduces a new class of things - monoids that support enough introspection to allow equality; and at this point there is a reasonable argument that an Eq-Monoid thing goes against the spirit of its Monoid superclass (Monoids are opaque). As this is both a new class of objects and potentially contentious - a standard implementation won't exist.
First, your mor function looks rather suspicious because it requires a Monoid but never uses mappend, and so it is significantly more constrained than necessary.
mor :: (Eq a, Monoid a) => a -> a -> a
mor a b = if a /= mempty then a else b
You could accomplish the same thing with merely a Default constraint:
import Data.Default
mor :: (Eq a, Default a) => a -> a -> a
mor a b = if a /= def then a else b
and I think that any use of Default should also be viewed warily because, as I believe many Haskellers complain, it is a class without principles.
My second thought is that it seems that the data type you're really dealing with here is Maybe (NonEmpty a), not [a], and the Monoid you're actually talking about is First.
import Data.Monoid
morMaybe :: Maybe a -> Maybe a -> Maybe a
morMaybe x y = getFirst (First x <> First y)
And so then we could use that with lists, as in your example, under the (nonEmpty, maybe [] toList) isomorphism between [a] and Maybe (NonEmpty a):
import Data.List.NonEmpty
morList :: [t] -> [t] -> [t]
morList x y = maybe [] toList (nonEmpty x `mor` nonEmpty y)
λ> mor'list [1] []
[1]
λ> mor'list [] [2]
[2]
λ> mor'list [1] [2]
[1]
(I'm sure that somebody more familiar with the lens library could provide a more impressive concise demonstration here, but I don't immediately know how.)
You could extend Monoid with a predicate to test whether an element is an identity.
class Monoid a => TestableMonoid a
where
isMempty :: a -> Bool
morTestable :: a -> a -> a
morTestable x y = if isMempty x then y else x
Not every monoid can have an instance of TestableMonoid, but plenty (including list) can.
instance TestableMonoid [a]
where
isMempty = null
We could even then write a newtype wrapper with a Monoid:
newtype Mor a = Mor { unMor :: a }
instance TestableMonoid a => Monoid (Mor a)
where
mempty = Mor mempty
Mor x `mappend` Mor y = Mor (morTestable x y)
λ> unMor (Mor [1] <> Mor [])
[1]
λ> unMor (Mor [] <> Mor [2])
[2]
λ> unMor (Mor [1] <> Mor [2])
[1]
So that leaves open the question of whether the TestableMonoid class deserves to exist. It certainly seems like a more "algebraically legitimate" class than Default, at least, because we can give it a law that relates it to Monoid:
isEmpty x iff mappend x = id
But I do question whether this actually has any common use cases. As I said earlier, the Monoid constraint is superfluous for your use case because you never mappend. So we should ask, then, can we envision a situation in which one might need both mappend and isMempty, and thus have a legitimate need for a TestableMonoid constraint? It's possible I'm being shortsighted here, but I can't envision a case.
I think this is because of something Stephen Tetley touched on when he said that this "goes against the spirit of its Monoid." Tilt your head at the type signature of mappend with a slightly different parenthesization:
mappend :: a -> (a -> a)
mappend is a mapping from members of a set a to functions a -> a. A monoid is a way of viewing values as functions over those values. The monoid is a view of the world of a only through the window of what these functions let us see. And functions are very limited in what they let us see. The only thing we ever do with them is apply them. We never ask anything else of a function (as Stephen said, we have no introspection into them). So although, yes, you can bolt anything you want onto a subclass, in this case the thing we're bolting on feels very different in character from the base class we are extending, and it feels unlikely that there would be much intersection between the use cases of functions and the use cases of things that have general equality or a predicate like isMempty.
So finally I want to come back around to the simple and precise way to write this: Write code at the value level and stop worrying classes. You don't need Monoid and you don't need Eq, all you need is an additional argument:
morSimple :: (t -> Bool) -- ^ Determine whether a value should be discarded
-> t -> t -> t
morSimple f x y = if f x then y else x
λ> morSimple null [1] []
[1]
λ> morSimple null [1] [2]
[1]
λ> morSimple null [] [2]
[2]

Can you overload + in haskell?

While I've seen all kinds of weird things in Haskell sample code - I've never seen an operator plus being overloaded. Is there something special about it?
Let's say I have a type like Pair, and I want to have something like
Pair(2,4) + Pair(1,2) = Pair(3,6)
Can one do it in haskell?
I am just curious, as I know it's possible in Scala in a rather elegant way.
Yes
(+) is part of the Num typeclass, and everyone seems to feel you can't define (*) etc for your type, but I strongly disagree.
newtype Pair a b = Pair (a,b) deriving (Eq,Show)
I think Pair a b would be nicer, or we could even just use the type (a,b) directly, but...
This is very much like the cartesian product of two Monoids, groups, rings or whatever in maths, and there's a standard way of defining a numeric structure on it, which would be sensible to use.
instance (Num a,Num b) => Num (Pair a b) where
Pair (a,b) + Pair (c,d) = Pair (a+c,b+d)
Pair (a,b) * Pair (c,d) = Pair (a*c,b*d)
Pair (a,b) - Pair (c,d) = Pair (a-c,b-d)
abs (Pair (a,b)) = Pair (abs a, abs b)
signum (Pair (a,b)) = Pair (signum a, signum b)
fromInteger i = Pair (fromInteger i, fromInteger i)
Now we've overloaded (+) in an obvious way, but also gone the whole hog and overloaded (*) and all the other Num functions in the same, obvious, familiar way mathematics does it for a pair. I just don't see the problem with this. In fact I think it's good practice.
*Main> Pair (3,4.0) + Pair (7, 10.5)
Pair (10,14.5)
*Main> Pair (3,4.0) + 1 -- *
Pair (4,5.0)
* - Notice that fromInteger is applied to numeric literals like 1, so this was interpreted in that context as Pair (1,1.0) :: Pair Integer Double. This is also quite nice and handy.
Overloading in Haskell is only available using type classes. In this case, (+) belongs to the Num type class, so you would have to provide a Num instance for your type.
However, Num also contains other functions, and a well-behaved instance should implement all of them in a consistent way, which in general will not make sense unless your type represents some kind of number.
So unless that is the case, I would recommend defining a new operator instead. For example,
data Pair a b = Pair a b
deriving Show
infixl 6 |+| -- optional; set same precedence and associativity as +
Pair a b |+| Pair c d = Pair (a+c) (b+d)
You can then use it like any other operator:
> Pair 2 4 |+| Pair 1 2
Pair 3 6
I'll try to come at this question very directly, since you are keen on getting a straight "yes or no" on overloading (+). The answer is yes, you can overload it. There are two ways to overload it directly, without any other changes, and one way to overload it "correctly" which requires creating an instance of Num for your datatype. The correct way is elaborated on in the other answers, so I won't go over it.
Edit: Note that I'm not recommending the way discussed below, just documenting it. You should implement the Num typeclass and not anything I write here.
The first (and most "wrong") way to overload (+) is to simply hide the Prelude.+ function, and define your own function named (+) that operates on your datatype.
import Prelude hiding ((+)) -- hide the autoimport of +
import qualified Prelude as P -- allow us to refer to Prelude functions with a P prefix
data Pair a = Pair (a,a)
(+) :: Num a => Pair a -> Pair a -> Pair a -- redefinition of (+)
(Pair (a,b)) + (Pair (c,d)) = Pair ((P.+) a c,(P.+) b d ) -- using qualified (+) from Prelude
You can see here, we have to go through some contortions to hide the regular definition of (+) from being imported, but we still need a way to refer to it, since it's the only way to do fast machine addition (it's a primitive operation).
The second (slightly less wrong) way to do it is to define your own typeclass that only includes a new operator you name (+). You'll still have to hide the old (+) so haskell doesn't get confused.
import Prelude hiding ((+))
import qualified Prelude as P
data Pair a = Pair (a,a)
class Addable a where
(+) :: a -> a -> a
instance Num a => Addable (Pair a) where
(Pair (a,b)) + (Pair (c,d)) = Pair ((P.+) a c,(P.+) b d )
This is a bit better than the first option because it allows you to use your new (+) for lots of different data types in your code.
But neither of these are recommended, because as you can see, it is very inconvenient to access the regular (+) operator that is defined in the Num typeclass. Even though haskell allows you to redefine (+), all of the Prelude and the libraries are expecting the original (+) definition. Lucky for you, (+) is defined in a typeclass, so you can just make Pair an instance of Num. This is probably the best option, and it is what the other answerers have recommended.
The issue you are running into is that there are possibly too many functions defined in the Num typeclass (+ is one of them). This is just a historical accident, and now the use of Num is so widespread, it would be hard to change it now. Instead of splitting those functionalities out into separate typeclasses for each function (so they can be overridden separately) they are all glommed together. Ideally the Prelude would have an Addable typeclass, and a Subtractable typeclass etc. that allow you to define an instance for one operator at a time without having to implement everything that Num has in it.
Be that as it may, the fact is that you will be fighting an uphill battle if you want to write a new (+) just for your Pair data type. Too much of the other Haskell code depends on the Num typeclass and its current definition.
You might look into the Numeric Prelude if you are looking for a blue-sky reimplementation of the Prelude that tries to avoid some of the mistakes of the current one. You'll notice they've reimplemented the Prelude just as a library, no compiler hacking was necessary, though it's a huge undertaking.
Overloading in Haskell is made possible through type classes. For a good overview, you might want to look at this section in Learn You a Haskell.
The (+) operator is part of the Num type class from the Prelude:
class (Eq a, Show a) => Num a where
(+), (*), (-) :: a -> a -> a
negate :: a -> a
...
So if you'd like a definition for + to work for pairs, you would have to provide an instance.
If you have a type:
data Pair a = Pair (a, a) deriving (Show, Eq)
Then you might have a definition like:
instance Num a => Num (Pair a) where
Pair (x, y) + Pair (u, v) = Pair (x+u, y+v)
...
Punching this into ghci gives us:
*Main> Pair (1, 2) + Pair (3, 4)
Pair (4,6)
However, if you're going to give an instance for +, you should also be providing an instance for all of the other functions in that type class too, which might not always make sense.
If you only want (+) operator rather than all the Num operators, probably you have a Monoid instance, for example Monoid instance of pair is like this:
class (Monoid a, Monoid b) => Monoid (a, b) where
mempty = (mempty, mempty)
(a1, b1) `mappend` (a2, b2) = (a1 `mappend` a2, b1 `mappend` b2)
You can make (++) a alias of mappend, then you can write code like this:
(1,2) ++ (3,4) == (4,6)
("hel", "wor") ++ ("lo", "ld") == ("hello", "world")

Resources