In my attempt to understand existential types I've read that Church encoding along with the Rank-N-types extension would be sufficient to encode them in Haskell without existential quantification. I found this straightforward example:
type Obj = forall y. (forall x. (Show x) => x -> y) -> y
obj :: Obj
obj f = f "hello"
app :: Obj -> String
app obj = obj (\x -> show x)
In the Haskell Wiki I stumbled upon the following example of a heterogeneous list based on an existential type:
data Obj = forall a. (Show a) => Obj a
xs :: [Obj]
xs = [Obj 1, Obj "foo", Obj 'c']
doShow :: [Obj] -> String
doShow [] = ""
doShow ((Obj x):xs) = show x ++ doShow xs
Now I tried to express this implementation with Church and failed with an illegal polymorphic type error:
type Obj = forall y. (forall x. (Show x) => x -> y) -> y
obj1 :: Obj
obj1 f = f 1
obj2 :: Obj
obj2 f = f "foo"
obj3 :: Obj
obj3 f = f 'c'
xs :: [Obj]
xs = [obj1, obj2, obj3]
doShow :: [Obj] -> String
doShow [] = ""
doShow (obj:xs) = obj (\x -> show x ++ doShow xs)
I guess this translation is pretty schematic and just plain wrong. Is it right that existential types can be encoded with Church/Rank-N? How is it done properly?