Skip to content

Instantly share code, notes, and snippets.

@alios
Created November 6, 2011 06:57
Show Gist options
  • Save alios/1342569 to your computer and use it in GitHub Desktop.
Save alios/1342569 to your computer and use it in GitHub Desktop.
type system problems with type families and classes
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
import Data.Bits
import Data.Word
class (Bits (T c)) => C c where
type T c :: *
f1 :: (T c, T c) -> (T c, T c)
f1 (a, b) =
let x = a .&. b
y = x .|. complement b
in (x, y)
f2 :: (T c, T c) -> T c
f2 = fst . f1
data D
instance C D where
type T D = Word32
{-
fail.hs:18:14:
Could not deduce (T c0 ~ T c)
from the context (C c)
bound by the class declaration for `C'
at /home/alios/src/lab/fail.hs:(8,1)-(18,15)
NB: `T' is a type function, and may not be injective
Expected type: (T c, T c) -> (T c, T c)
Actual type: (T c0, T c0) -> (T c0, T c0)
In the second argument of `(.)', namely `f1'
In the expression: fst . f1
Failed, modules loaded: none.
-}
{-
The code above was a reduced form. To get the idea what I was really trying to express is the code below.
The first thing I wrote down was the instance declaration below, which looked pretty nice and expressiv to me...
-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
import Data.Word
import Data.Bits
import Data.Text (Text)
type Netmask f = Address f
class (Bits (Address f)) => AddressFamily f where
type Address f :: *
network :: (Address f, Address f) -> Address f
network = fst . networkRange
networkRange :: (Address f) -> (Address f, Address f)
networkRange (a, m) =
let nwAddr = a .&. m
bcAddr = nwAddr .|. complement m
in (nwAddr, bcAddr)
data IPv4
instance AddressFamily IPv4 where
type Address IPv4 = Word32
@alios
Copy link
Author

alios commented Nov 6, 2011

It is not realy about getting the problem solved, its more that I need to come uppon a real use for language feature, to have the feeling that I realy understood what the possiblities and use cases of that lang feature are... TypeFamilies are still open at the moment on my list ;-)

So what I realy liked here were two things:

  • a data type with a signature like Address IPv4
  • the way to write the class implementation and say f.e.: the type Address IPv4 = Word32

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