id,summary,reporter,owner,description,type,status,priority,milestone,component,version,resolution,keywords,cc,os,architecture,failure,difficulty,testcase,blockedby,blocking,related
2239,lack of improvement/reduction with TFs,claus,simonpj,"{{{
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
data A = A
data B = B

class C a where c :: a -> String
instance C Bool where c _ = ""Bool""
instance C Char where c _ = ""Char""

-- via TFs
type family TF a
type instance TF A = Char
type instance TF B = Bool

tf :: forall a b. (b ~ TF a,C b) => a -> String
tf a = c (undefined:: b) 

-- via FDs
class FD a b | a -> b
instance FD A Char
instance FD B Bool

fd :: forall a b. (FD a b,C b) => a -> String
fd a = c (undefined:: b) 
}}}
for some reason, the TF version doesn't work as well as the FD version:
{{{
*Main> fd A
""Char""
*Main> fd B
""Bool""
*Main> tf A

<interactive>:1:0:
    No instance for (C (TF A))
      arising from a use of `tf' at <interactive>:1:0-3
    Possible fix: add an instance declaration for (C (TF A))
    In the expression: tf A
    In the definition of `it': it = tf A
*Main> :t undefined :: (b~TF A)=>b
undefined :: (b~TF A)=>b :: TF A
*Main> :t undefined :: (FD A b)=>b
undefined :: (FD A b)=>b :: Char
}}}
this is with `GHCi, version 6.9.20080217`.

the result of the TF is ""known"", even if not used:
{{{
*Main> :t undefined :: (b~TF A,b~Char)=>b
undefined :: (b~TF A,b~Char)=>b :: TF A
*Main> :t undefined :: (b~TF A,b~Bool)=>b

<interactive>:1:0:
    Couldn't match expected type `Bool' against inferred type `Char'
}}}",bug,closed,low,7.0.1,Compiler (Type checker),6.12.3,fixed,TF FD,,Unknown/Multiple,Unknown/Multiple,None/Unknown,Unknown,indexed-types/should_fail/T2239,,,
