Question

I want to express that I have 3 related typeclasses.

I have two files. First:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
module ModA where

class Class a b c | a -> b, b -> c where
    getB :: a -> b
    getC :: b -> c

Second:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
module B where

import qualified ModA

data A = A {f1::String}

data B = B {f2::String}

data C = C {f3::String}

instance ModA.Class A B C where
    getB a = B "hey"
    getC a = C "ho"

getABForMe = ModA.getB (A "boo")

getACForMe = ModA.getC (B "yo")

The error I get:

No instance for (ModA.Class a0 B C)
  arising from a use of `ModA.getC'
Possible fix: add an instance declaration for (ModA.Class a0 B C)
In the expression: ModA.getC (B "yo")
In an equation for `getACForMe': getACForMe = ModA.getC (B "yo")

What am I missing?

Was it helpful?

Solution

You can make the functional dependency "circular":

class Class a b c | a->b, b->c, c->a where
    getB :: a -> b
    getC :: b -> c

so any one type parameter can be deduced from any of the others. But I'm not sure if you really want this; why not have just a type class with one fundep and one method, and make two instances of it (instance Class A B and instance Class B C)?

OTHER TIPS

GHC cannot know the type of the first class parameter a in the call of getC. The call fixes b to be of type B, and the functional dependency then allows GHC to infer that c must be C. But no information on a is available.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top