Skip to content

Instantly share code, notes, and snippets.

@gatlin
Created July 25, 2014 16:35
Show Gist options
  • Select an option

  • Save gatlin/1286e39afc540a3ca804 to your computer and use it in GitHub Desktop.

Select an option

Save gatlin/1286e39afc540a3ca804 to your computer and use it in GitHub Desktop.
Type operators
Type operators!
===
Turns out a GHC language extension makes a lot of cool things possible that I
think you hinted at:
> {-# LANGUAGE TypeOperators #-}
> data a + b = Inl a | Inr b deriving Show
> data a * b = a :*: b deriving Show
> type Name = String
> type Age = Integer
> type TaxId = String
> type Human = Name * Age
> type Corporation = Name * Age * TaxId
> type Person = Human + Corporation
Note how I constructed `Human` and `Corporation`: I can mix and match and
create new types this way, but `Name` and `Age` etc are still available as
types on their own.
I'll create a human:
> gatlin :: Human
> gatlin = "gatlin" :*: 25
and a corporation:
> walmart :: Corporation
> walmart = "Wal-Mart"
> :*: 52
> :*: "710415188"
Now I can define a function that works on people:
> salute :: Person -> String
And handle completely different cases:
> -- Human
> salute (Inl (n :*: a)) = "Hello, my name is "
> ++ n
> ++ " and I am "
> ++ (show a)
> ++ " years old."
> -- Corporation
> salute ( Inr (n :*: a :*: t)) = "I am a corporation entitled "
> ++ n
> ++ " (tax id: "
> ++ t
> ++ ") founded "
> ++ (show a)
> ++ " years ago."
The `+` type is really just the standard `Either` type available in the base
libraries, but it's useful to expose it for what it really is.
In ghci, you can do this now:
ghci> salute $ Inl gatlin
ghci> salute $ Inr walmart
ghci> salute . Inl $ "George Washington" :*: 282
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment