eps*_*lbe 8 haskell types class
您好Haskellers和Haskellettes,
我已经花了很长一段时间在Haskell上摆弄,但是有一个我无法理解的类概念.在以下示例中,我的数据类型为ExprTree
data Val a = Num a | Var String deriving (Eq, Ord, Show)
data ExprTree = Leaf {lab::Label, val::(Val a)=> a}
| Node {lab::Label, fun::Fun, lBranch::ExprTree, rBranch::ExprTree}
deriving(Eq,Ord)
Run Code Online (Sandbox Code Playgroud)
这导致
Type constructor `Val' used as a class In the definition
of data constructor `Leaf' In the data type declaration for `ExprTree'
Run Code Online (Sandbox Code Playgroud)
我也试过了
data ExprTree' = Leaf {lab::Label, val::Val}
...
Run Code Online (Sandbox Code Playgroud)
但随机改变的类型签名 - 既没有效果,也没有提供启示.
现在据我所知,Num a表示类的东西,Num但这不是数据类型的实例 - 并且不让我编译.那么我需要做些什么才能做好ExprTree定义.
提前感谢您的提示和想法!
编辑:
1)感谢快速的答案!
2)I改变val::(Val a)=>a到val::Val a
我有类似的东西 - 然后错误:Not in scope type variable a发生你有额外的建议?
回答标题中的问题:在讨论Haskell时,"类"这个词几乎总是用来表示"类型类",因为它是Haskell中唯一的类.所以没有区别.
要回答你体内的问题:
data ExprTree a =
Leaf {lab::Label, val::(Val a)}
| Node {lab::Label, fun::Fun, lBranch::(ExprTree a), rBranch::(ExprTree a)}
deriving(Eq,Ord)
Run Code Online (Sandbox Code Playgroud)
写入(Val a)=>a是没有意义的,因为Val它不是类型类,你不能只在类型定义的右侧引入类型类约束(无论如何都没有扩展 - 无论哪种方式都不是你想要的).
正确的类型是
data Val a = Num a | Var String deriving (Eq, Ord, Show)
data ExprTree a = Leaf {lab::Label, val :: Val a}
| Node {lab::Label, fun::Fun, lBranch::ExprTree a, rBranch::ExprTree a}
deriving(Eq,Ord)
Run Code Online (Sandbox Code Playgroud)
由于该类型Val需要一个额外的类型参数,因此每次使用它时都需要提供一个*。我使用了一个类型变量,就像最初的定义一样;这要求变量也被命名为 的参数ExprTree。(其他可能性是使用具体类型,例如IntorMaybe String等,或使用存在类型;这两种类型在这里都没有意义。)
您实际使用的是类型类上下文(“类”只是“类型类”的简写)。 Val是一种类型,而不是类型类,因此它在那里不合法。
*这并不完全正确;你需要一种类型*。种类是类型的类型: Inthas kind *、Val ahas kind *、Valhas kind * -> *。也就是说,它本身Val就是一个类型函数,需要参数才能成为完整类型。