Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell中多态列表的折叠_Haskell_Generic Programming_Existential Type_Higher Rank Types - Fatal编程技术网

Haskell中多态列表的折叠

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 --或者作为一个褶皱 我的折叠

在一个大型Haskell应用程序中,我有一个分布在多种类型的记录集合,这些记录相互引用。所有涉及的类型都实现了一个通用的typeclass。typeclass包含处理变量及其所有子变量的函数,非常像uniplate的函数

这是我想要构建的一个简化的代码示例。在GHC中实现给定类型类的记录字段是否有可能(且合理)实现通用功能

{-#语言等级}
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的值列表,无论您将实现什么类型的类,并且您不能在这里破坏类型系统

你可以:

  • 使用上文建议的特殊框类型。这简直太难看了

  • 通过消息传递实现通用接口

    数据Foo=Foo{foocont::Int}

    bar=Foo 2

    baz=foo3


  • 根据我对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