Haskell中多态列表的折叠
在一个大型Haskell应用程序中,我有一个分布在多种类型的记录集合,这些记录相互引用。所有涉及的类型都实现了一个通用的typeclass。typeclass包含处理变量及其所有子变量的函数,非常像uniplate的函数 这是我想要构建的一个简化的代码示例。在GHC中实现给定类型类的记录字段是否有可能(且合理)实现通用功能Haskell中多态列表的折叠,haskell,generic-programming,existential-type,higher-rank-types,Haskell,Generic Programming,Existential Type,Higher Rank Types,在一个大型Haskell应用程序中,我有一个分布在多种类型的记录集合,这些记录相互引用。所有涉及的类型都实现了一个通用的typeclass。typeclass包含处理变量及其所有子变量的函数,非常像uniplate的函数 这是我想要构建的一个简化的代码示例。在GHC中实现给定类型类的记录字段是否有可能(且合理)实现通用功能 {-#语言等级} myPara::对于所有a r。(数据a,Foo a) =>(对于所有b.Foo b=>b->[r]->r) ->a ->r --或者作为一个褶皱 我的折叠
{-#语言等级}
myPara::对于所有a r。(数据a,Foo a)
=>(对于所有b.Foo b=>b->[r]->r)
->a
->r
--或者作为一个褶皱
我的折叠::对于所有的一个r。(数据a,Foo a)
=>(对于所有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编译此文件(显然)失败:
副本hs:21:42:
约束中不明确的类型变量“a0”:
(数据a0)因在复制时使用“实例”而产生:21:42-50
(Foo a0)由于在repo.hs中使用“实例”而产生:21:42-50
可能修复:添加修复这些类型变量的类型签名
在'foldl'的第三个参数中,即'instances'
在表达式中:foldl(\x y->x+fooConst y)0个实例
在“func”的方程式中:
func
=foldl(\x y->x+fooConst y)0个实例
哪里
实例::forall a。(数据a,Foo a)=>[a]
实例=universeBi条
bar=bar{barBaz=baz}
baz=baz{barBar=bar}
有一阵子了
您是否尝试过存在量化的数据构造函数
data Foo = forall a. MyTypeClass a => Bar [a]
func (Bar l) = map typeClassMember a
现在,func
将处理Foo类型的任何东西,它隐藏了内部类型。您已经点击了
除了需要编译器时的情况外,您不应该在任何情况下使用TypeClass
来帮你猜一下类型。类型x的值列表将保留类型x的值列表,无论您将实现什么类型的类,并且您不能在这里破坏类型系统
你可以:
根据我对uniplate文档的阅读,
实例的类型应该是[Baz]
,不是吗?是的,这更像是一个理论问题。我不确定我是否理解理论问题。你能在你的文本中把它写得更精确一点吗?(当你问“有可能获得像这样的通用功能吗?”“像这样”是什么意思?)你开始抽象类型类,Haskell非常不擅长。使类具体化:例如,对于Eq
,使用数据Eq a=Eq{Eq::a->a->Bool}
,然后将其作为参数传递。TypeClass主要是为了方便记法,让函数来完成繁重的工作。看来GHC 7.4中的ConstraintTypes可能是可行的。我想要的是一个通用函数,类似于universeBi(来自uniplate),它对TypeClass而不是类型进行抽象。我已经有了你推荐的函数,但是我有很多函数,我正试图简化大量的代码。
data Foo = forall a. MyTypeClass a => Bar [a]
func (Bar l) = map typeClassMember a