Skip to content

Instantly share code, notes, and snippets.

@jbpotonnier
Created August 13, 2012 20:32
Show Gist options
  • Save jbpotonnier/3343902 to your computer and use it in GitHub Desktop.
Save jbpotonnier/3343902 to your computer and use it in GitHub Desktop.
I try to understand phantom types in Haskell. In main, try eur 12 <+> usd 23 and see the compilation error, saying that you cannot add euros and US dollars. Neat ;)
data EUR
data USD
data Amount a = Amount Float deriving Show
eur :: Float -> Amount EUR
eur a = Amount a
usd :: Float -> Amount USD
usd a = Amount a
(<+>) :: Amount a -> Amount a -> Amount a
(Amount a) <+> (Amount b) = Amount (a + b)
main = do
print $ eur 12 <+> eur 23
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype Feet = Feet Double deriving (Num, Show, Eq)
newtype Cm = Cm Double deriving (Num, Show, Eq)
main =
print $ Feet 12 + Feet 12
@jpcaruana
Copy link

duplication

@jbpotonnier
Copy link
Author

GeneralizedNewtypeDeriving is providing derivation for numeric behaviour (Num typeclass)
It is less verbose than phantom types, no need for "smart constructors" (eur and usd), and all numeric functions for free.
I guess GeneralizedNewtypeDeriving is one of the many reasons ghc is so big :P

@jbpotonnier
Copy link
Author

Deriving Num means that an expression like 12 + Feet 34 is valid, because Feed is now like a Num. It may or may not be what you want, depending of your application. I think if you define some new types that must not mix, then you don't want to mix them with Num.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment