packages feed

hid-examples-0.5: ch11/data-families/Main.hs

{-# LANGUAGE TypeFamilies #-}


data family XList a
data instance XList () = XListUnit Integer
data instance XList Bool = XBits Integer Integer
data instance XList Char = XCons Char (XList Char) | XNil

class XListable a where
  xempty :: XList a
  xcons :: a -> XList a -> XList a
  xheadMay :: XList a -> Maybe a

instance XListable () where
  xempty = XListUnit 0
  
  xcons () (XListUnit n) = XListUnit (n + 1)
  
  xheadMay (XListUnit 0) = Nothing
  xheadMay _ = Just ()

instance XListable Bool where
  xempty = XBits 0 0
  
  xcons b (XBits bits n) = XBits (bits * 2 + if b then 1 else 0) (n + 1) 

  xheadMay (XBits bits n)
    | n <= 0 = Nothing
    | otherwise = Just (bits `mod` 2 /= 0)

instance XListable Char where
  xempty = XNil
  xcons x xs = XCons x xs

  xheadMay (XCons c _) = Just c
  xheadMay XNil = Nothing

test :: (Eq a, XListable a) => a -> Bool
test a = xheadMay (xcons a xempty) == Just a

main = print $ and [test (),
                    test True,
                    test False,
                    test 'x']