Skip to content

Instantly share code, notes, and snippets.

@gallais
Created December 22, 2015 00:34
Show Gist options
  • Select an option

  • Save gallais/b08d7ba495ea2e91968c to your computer and use it in GitHub Desktop.

Select an option

Save gallais/b08d7ba495ea2e91968c to your computer and use it in GitHub Desktop.
Singletons, Classes, etc.
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
module UnitLength where
newtype Length (a::UnitLength) b = Length { payload :: b } deriving (Eq,Show)
data UnitLength = Meter
| KiloMeter
| Miles
deriving (Eq,Show)
data SUnitLength (a :: UnitLength) where
SMeter :: SUnitLength Meter
SKiloMeter :: SUnitLength KiloMeter
SMiles :: SUnitLength Miles
display :: Show b => SUnitLength a -> Length a b -> String
display sa l = show (payload l) ++
case sa of
SKiloMeter -> "km"
_ -> "m"
class CUnitLength (a :: UnitLength) where
getUnit :: Length a b -> SUnitLength a
instance CUnitLength Meter where
getUnit _ = SMeter
instance CUnitLength KiloMeter where
getUnit _ = SKiloMeter
instance CUnitLength Miles where
getUnit _ = SMiles
getUnit' :: CUnitLength a => SUnitLength a
getUnit' = getUnit (undefined :: Length a ())
display' :: (CUnitLength a, Show b) => Length a b -> String
display' = display getUnit'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment