Vector and Monoids

Today I was playing around with Haskell and Monoids, and here’s what I came up with:

import Data.Monoid

data Vector = Vector (Int, Int) deriving (Show)
newtype SumVector = SumVector Vector deriving (Show)
newtype ProductVector = ProductVector Vector deriving (Show)

instance Monoid (SumVector) where
mempty = SumVector $ Vector (0, 0)
SumVector (Vector (a, b)) `mappend` SumVector (Vector (c, d)) = SumVector $ Vector (a+c, b+d)

instance Monoid (ProductVector) where
mempty = ProductVector $ Vector (1, 1)
ProductVector (Vector (a, b)) `mappend` ProductVector (Vector (c, d)) = ProductVector $ Vector (a*c, b*d)

What I was interested in, what is the difference between newtype and data? Since when I replaced newtype with data, the code worked as expected.
Here’s what I got as an answer:

 what is the main difference between data and newtype?
Bor0: newtype has the same runtime representation as the underlying type
data can do sum types (using |) and multi-element records
you'd use newtype for performance reasons, when it is possible to do so
also, you can use GeneralizedNewtypeDeriving to pull existing instances into your new type
e.g., suppose you have data Foobar { ... } and instance ToJSON Foobar
then you can do newtype Baz = Baz Foobar deriving (ToJSON)
you can't do that with data Baz = Baz Foobar

Leave a comment