id,summary,reporter,owner,description,type,status,priority,milestone,component,version,resolution,keywords,cc,os,architecture,failure,testcase,blockedby,blocking,related,differential
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
:1:0:
No instance for (C (TF A))
arising from a use of `tf' at :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
: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,indexed-types/should_fail/T2239,,,,