1 | > {-# LANGUAGE TypeFamilies #-} |
---|

2 | |
---|

3 | Suppose I have a class C, |
---|

4 | |
---|

5 | > class C a where |
---|

6 | > type E a |
---|

7 | > c :: E a -> a -> a |
---|

8 | |
---|

9 | a datatype T, |
---|

10 | |
---|

11 | > data T a = T a |
---|

12 | |
---|

13 | and an instance of C for T |
---|

14 | |
---|

15 | > instance C (T a) where |
---|

16 | > type E (T a) = a |
---|

17 | > c x (T _) = T x |
---|

18 | |
---|

19 | I would like to write a function such as f |
---|

20 | |
---|

21 | > f t@(T x) = c x t |
---|

22 | |
---|

23 | without a type signature. Unfortunately, I can't because GHC tells me |
---|

24 | |
---|

25 | Couldn't match expected type `t' against inferred type `T (E t)' |
---|

26 | In the second argument of `c', namely `t' |
---|

27 | In the expression: c x t |
---|

28 | In the definition of `f': f (t@(T x)) = c x t |
---|

29 | |
---|

30 | There are at least three possible ways to write the above code such |
---|

31 | that it works. |
---|

32 | |
---|

33 | (1) Give a type signature for f |
---|

34 | |
---|

35 | > {- |
---|

36 | > f :: T a -> T a |
---|

37 | > -} |
---|

38 | |
---|

39 | (2) Define the class C using an equality constraint |
---|

40 | |
---|

41 | > {- |
---|

42 | > class C t where |
---|

43 | > type E t |
---|

44 | > c :: (E t ~ e) => e -> t -> t |
---|

45 | > -} |
---|

46 | |
---|

47 | (3) Define the class C using functional dependencies |
---|

48 | |
---|

49 | > {- |
---|

50 | > class C t e | t -> e where |
---|

51 | > c :: e -> t -> t |
---|

52 | > -} |
---|

53 | |
---|

54 | But the real question is why don't I get a type for f? |
---|

55 | |
---|

56 | This has been tested in GHC 6.10.1 and 6.12.1. |
---|