Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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_Typeclass_Type Families - Fatal编程技术网

Haskell 将数据、类型和函数绑定在一起

Haskell 将数据、类型和函数绑定在一起,haskell,typeclass,type-families,Haskell,Typeclass,Type Families,我想对一棵规则结构的大树(或森林)建模——树可以分解为小树(不规则部分)和(即)大参数列表,每个参数和每个节点构成一个大树节点 所以,我想要一个数据结构,其中树中的每个节点代表许多节点。而实际节点的类型为(node,param) 对于处理这类树的算法,param不会对其进行筛选。它们只是占位符。但是一些数据应该可以从普通参数或节点和参数的组合中提取,并且所有可能的参数都应该是可匹配的。所有这些类型的数据都是先验的,它们反映了树的语义 所以,param的实际类型、语义和内容取决于树的实现 C++

我想对一棵规则结构的大树(或森林)建模——树可以分解为小树(不规则部分)和(即)大参数列表,每个参数和每个节点构成一个大树节点

所以,我想要一个数据结构,其中树中的每个节点代表许多节点。而实际节点的类型为(node,param)

对于处理这类树的算法,param不会对其进行筛选。它们只是占位符。但是一些数据应该可以从普通参数或节点和参数的组合中提取,并且所有可能的参数都应该是可匹配的。所有这些类型的数据都是先验的,它们反映了树的语义

所以,param的实际类型、语义和内容取决于树的实现

C++中使用嵌套类型DEFS对PARAMS模型进行建模,对于算法应该使用的所有类型的固定方法名称(这两个概念一起构成)和算法本身模板。 也就是说,如果我想将大树的每个节点关联为一个整数,我将提供一个函数

int data(const node&n,const param&p)
,其中
param
可以作为嵌套的typedef使用,算法可以得到所有可用参数的列表,并使用感兴趣的节点和每个参数调用
data


我有一些简单的数据类型,例如树数据,如下所示

data Tree = Node [Tree] | Leaf
现在我想打包:

  • 混凝土树
  • 某种类型
  • 这种类型的一些值
  • 在树节点和值上操作的一些函数
因此,我们可以编写一些使用这种打包类型和函数的函数,比如,泛型方法

如何做到这一点


我来到了一个典型的家庭

class PackagedUp t where
  type Value t

  tree :: Tree t
  values :: [Value t]
  f :: Tree t -> Value t -> Int
Tree
现在变为
treet t
,因为类型族希望其成员的类型依赖于类型类参数

此外,与类型族一样,还需要处理注入性

有了这个我可以

instance PackagedUp MyTree where
  type Value MyTree = (Int,Int)
  tree = Leaf
  values = [(0,0),(1,1)]
  f t v = fst v

现在如何编写这样的函数?也就是说,一个函数将以一棵树的根、所有值和所有树值的
[Int]
为根。首先,树类型的定义如下:

data Tree a = Node a [Tree a] | Leaf

上面的类型是多态的。就语义而言,它类似于我们在OO术语中所称的泛型类型(在C#或Java中,我们可能会编写
树模块,它提供了一个与您想要定义的非常相似的数据结构。

您对
树的定义不是您想要的,我非常确定您不需要走到类型族的地步来解决您的问题。然而,为了给出一个有用的答案,我们需要知道您想要的
fFunctor
就是这样一个接口,因为
fmap
可以处理树、列表和大量其他数据结构。但是,在您的情况下,您只有一个数据类型,因此不需要从中提取类型类。获取或返回
树a
的函数的多态性就足够了例如,我在上面定义的
getRoot
可以处理包含任何类型元素的树。我刚刚意识到,函数可以是
数据的成员,因此我可以在不使用
类的情况下拆分实现和调用
!虽然它不在
基中
,但
似乎是be a.
getRoot
将被称为
extract
。事实上,定义的
看起来非常类似于a。@MikhailCheshkov试图将Haskell当作一种OO语言来编写,这在绝大多数情况下只会导致头痛。耦合问题在Haskell中的表现方式与在OOP中不同,并且因此,解决方案也不同。如果你想自由地改变实现,大部分时候你需要做的就是将你的函数放在一个模块中,然后只导出你想在公共API中导出的函数。这就是augustss在提到模块时的意思。
getRoot :: Tree a -> Maybe a
getRoot Leaf       = Nothing
getRoot (Node x _) = Just x
instance Functor Tree where
    fmap f Leaf        = Leaf
    fmap f (Node x ts) = Node (f x) (fmap f ts)
fmap :: Functor f => (a -> b) -> f a -> f b
fmap :: (a -> b) -> Tree a -> Tree b
fmap :: (a -> b) -> [a] -> [b]