Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DefaultSignatures and associated type families

Is there a way to use DefaultSignatures extension with associated type families.

Here is an example why I need it.

class Foo p where
  type Back p :: *
  type Forward p :: *
  customFunc :: p -> IO ()

newtype Bar a = Bar (Forward a)

data Bat = Bat

type family ForwardBar a :: *

type instance ForwardBar Bat = Int

instance Foo (Bar Bat) where
  type Back (Bar Bat) = Bat
  type Forward (Bar Bat) = ForwardBar Bat
  customFunc _ = print "I am different customFunc and this is Bat Bat"

Now I want whenever p ~ Bar x then type Back (Bar x) = x and type ForwardBar (Bar x) = Forward x. I want to auto derive this whenever I am defining instance for some Bar x. However, definition of customFunc is different. Is this possible?

Also is it possible to add default signatures to functions of a class in another file (or package). I am using some class which I want to add default signatures but I dont want to modify the class definition itself.

like image 212
Satvik Avatar asked Feb 28 '14 06:02

Satvik


1 Answers

AFAIK, there's currently no possibility to use DefaultSignatures with type families.

I can see two options to do what you want. Both have certain disadvantages, but perhaps they're sufficient for your purposes.

Option 1: Use normal associated type default definitions

class Foo p where
  type Back p :: *
  type Back p = UnBar p
  type Forward p :: *
  type Forward p = ForwardBar (UnBar p)
  customFunc :: p -> IO ()

Requires a helper type family UnBar:

type family UnBar a :: *
type instance UnBar (Bar a) = a

The instance can then be just:

instance Foo (Bar Bat) where
  customFunc _ = print "I am different customFunc and this is Bat Bat"

Option 2: Use type families instead

class Foo p where
  customFunc :: p -> IO ()

type family Back p :: *
type family Forward p :: *

Now we can give a general instance for the type families for all Bar types:

type instance Back (Bar a) = a
type instance Forward (Bar a) = ForwardBar a

And more specific instances for the class, for concrete Bar types:

instance Foo (Bar Bat) where
  customFunc _ = print "I am different customFunc and this is Bat Bat"
like image 105
kosmikus Avatar answered Sep 17 '22 18:09

kosmikus