Expressing type relations with functional dependencies in Haskell

I want to express that I have 3 related classes.

I have two files. Firstly:

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

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

      

Secondly:

{-# 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 am getting:

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?

+3


source to share


2 answers


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

      



therefore, any parameter of one type can be inferred from any other. But I'm not sure if you really want this; why you do not have only one class type with hazelnuts and a method and make the two instances ( instance Class A B

and instance Class B C

)?

+6


source


GHC cannot know the type of the first class parameter a

in the call getC

. The call captures b

as a type b

, and then the functional dependency allows the GHC to infer what it c

should be c

. But a

there is no information about it.



+2


source







All Articles