Haskell 不推荐使用的替代方案-XDatatypeContext?

Haskell 不推荐使用的替代方案-XDatatypeContext?,haskell,Haskell,假设我想定义这样一棵树: {-# LANGUAGE DatatypeContexts #-} class Node a where getContent :: (Num a) => a data (Node a) => Tree a = Leaf a | Branch a (Tree a) (Tree a) data Tree a where Leaf :: (Node a) => a -> Tree a

假设我想定义这样一棵树:

{-# LANGUAGE DatatypeContexts #-}
class Node a where
  getContent :: (Num a) => a

data (Node a) => Tree a = Leaf a
                        | Branch a (Tree a) (Tree a)
data Tree a where
    Leaf :: (Node a) => a -> Tree a
    Branch :: (Node a) => a -> Tree a -> Tree a -> Tree a
-XDatatypeContexts现在不推荐使用。没有数据类型上下文是否可以做类似的事情?

您确定数据类型上下文确实做了您认为它做的事情吗?它被广泛地认为是一种不合适的特性,因为它所做的只是强迫您添加额外的约束,而不提供任何超出您没有它时所能得到的类型的保证

替代品,比如它,实际上做了一些有用的事情,是。您的类型的等效项如下所示:

{-# LANGUAGE DatatypeContexts #-}
class Node a where
  getContent :: (Num a) => a

data (Node a) => Tree a = Leaf a
                        | Branch a (Tree a) (Tree a)
data Tree a where
    Leaf :: (Node a) => a -> Tree a
    Branch :: (Node a) => a -> Tree a -> Tree a -> Tree a

在这种情况下,创建
值时需要
节点
约束,但在
值上进行模式匹配时,也会自动保证存在
节点
实例,使实例在函数类型中可用而不需要它作为参数接收
树a

非常感谢!虽然我认为你指的是分支::(节点a)=>a->Tree a->Treea@Jake:否--它的工作原理与函数类型签名类似,因此最后一个
树a
是结果数据类型<代码>树a->树a将只有一个子树。比较您当前拥有的
分支
构造函数的类型。你也可以写
数据树a=Node a=>Leaf a | Node a=>Branch a(Tree a)(Tree a)
。还有,对杰克说:cmccann所说的会起作用,但你完全确定这是你想要的吗?通常的方法是对使用
Tree
的函数施加约束,而不是对构造函数施加约束——例如
foo::Node a=>Tree a->……
——与此相比,它有一些重要的优势。在这种情况下,这对你不起作用有什么原因吗?@shachaf:对某人说话,就对他们说话。这将在他们的收件箱中发出通知,正如这条评论所示。