How do you get and use a dependent type from a type class with functional dependencies?
To clarify and give an example of my last attempt (minimized from the actual code that I wrote):
class Identifiable ab | a -> b where -- if you know a, you know b idOf :: a -> b instance Identifiable Int Int where idOf a = a f :: Identifiable Int b => Int -> [b] -- Does ghc infer b from the functional dependency used in Identifiable, and the instance? fa = [5 :: Int]
But ghc does not output b, it seems as it prints this error:
Couldn't match expected type 'b' with actual type 'Int' 'b' is a rigid type variable bound by the type signature for f :: Identifiable Int b => Int -> [b] at src/main.hs:57:6 Relevant bindings include f :: Int -> [b] (bound at src/main.hs:58:1) In the expression: 5 :: Int In the expression: [5 :: Int] In an equation for 'f': fa = [5 :: Int]
For context, here is a less minimal example:
data Graph a where Graph :: (Identifiable ab) => GraphImpl b -> Graph a getImpl :: Identifiable ab => Graph a -> GraphImpl b getImpl (Graph impl) = impl
The workaround here is to add b as type arg to Graph:
data Graph ab | a -> b where Graph :: (Identifiable ab) => GraphImpl b -> Graph a
Full context: I have Graph objects, each of which has an identifier, each object is assigned a value of 1 node. You can find the node object by object. I also have a Graph' , which consists of nodes (which entities can be assigned to), and to search for a node you need to provide the identifier node, which is Int. Graph uses Graph' internally. I have an IdMap that maps object identifiers to node identifiers in Graph' . This is my definition of Graph :
data Graph a where Graph :: (Identifiable ab) => { _idMap :: IdMap b, _nextVertexId :: Int, _graph :: Graph' a } -> Graph a
Answer : use family types, see Daniel Wagner's answer . For a full story, see Reid Burton's Answer .