在Haskell中折叠多态列表
  我有一个散布在大量Haskell应用程序中的多个类型的记录集合,这些应用程序可以相互引用。  所有涉及的类型都实现了一个常见的类型类。  类型类包含对变量及其所有子元素起作用的函数,非常类似于uniplate的para函数。 
这是我想要构建的简化代码示例。 是否有可能(和合理的)获得泛型功能来折叠在GHC中实现给定类型类型的记录字段...
{-# LANGUAGE RankNTypes #-}
myPara :: forall a r . (Data a, Foo a)
       => (forall b . Foo b => b -> [r] -> r)
       -> a
       -> r
-- or as a fold
myFold :: forall a r . (Data a, Foo a)
       => (forall b . Foo b => r -> b -> r)
       -> r
       -> b
       -> r
但是通用性足以与任意类型类型一起工作?
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Generics.Uniplate.Data
class Foo a where 
  fooConst :: a -> Int
data Bar = Bar {barBaz :: Baz} deriving (Typeable, Data)
instance Foo Bar where
  fooConst _ = 2
data Baz = Baz {barBar :: Bar} deriving (Typeable, Data)
instance Foo Baz where
  fooConst _ = 3
func :: Int
func = foldl ( x y -> x + fooConst y) 0 instances where
  instances :: forall a . (Data a, Foo a) => [a]
  instances = universeBi bar
  bar = Bar{barBaz = baz}
  baz = Baz{barBar = bar}
用GHC 7.2.1编译(显然)失败:
Repro.hs:21:42:
    Ambiguous type variable `a0' in the constraints:
      (Data a0) arising from a use of `instances' at Repro.hs:21:42-50
      (Foo a0) arising from a use of `instances' at Repro.hs:21:42-50
    Probable fix: add a type signature that fixes these type variable(s)
    In the third argument of `foldl', namely `instances'
    In the expression: foldl ( x y -> x + fooConst y) 0 instances
    In an equation for `func':
        func
          = foldl ( x y -> x + fooConst y) 0 instances
          where
              instances :: forall a. (Data a, Foo a) => [a]
              instances = universeBi bar
              bar = Bar {barBaz = baz}
              baz = Baz {barBar = bar}
你已经击中了存在的反模式。 除了需要编译器猜测类型的情况之外,您不应该使用类型类来进行任何操作。 x类型值的列表将保留x类型值的列表,而不管您将实现哪些类型类型,并且不能在此处打破类型系统。
您可以:
按照上面的建议使用ad-hoc盒子类型。 这简直太难看了。
使用消息传递实现通用接口。
数据Foo = Foo {fooConst :: Int}
bar = Foo 2
baz = Foo 3
已经有一段时间..
你有没有尝试过存在量化的数据构造函数?
data Foo = forall a. MyTypeClass a => Bar [a]
func (Bar l) = map typeClassMember a
  现在, func可以处理任何类型的Foo,它隐藏了内部类型。 
