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

Advertisements