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
Class haskell制造(a类)其他类的实例';_Class_Haskell_Types - Fatal编程技术网

Class haskell制造(a类)其他类的实例';

Class haskell制造(a类)其他类的实例';,class,haskell,types,Class,Haskell,Types,同样是哈斯凯勒和哈斯凯勒特 我仍然有一个问题,我真的不知道什么时候使用(a类)=>a,类型或 类型a其中类型是“联合类型”,例如Val和ExprTree 现在,我想通过添加几个实例使我的数据类型ExprTree更加通用: import Ratio data Fun = Add|Sub|Mul|Div|Pow deriving (Eq,Ord) instance Show Fun where show Add = "+" show Sub = "-" show Mu

同样是哈斯凯勒和哈斯凯勒特

我仍然有一个问题,我真的不知道什么时候使用
(a类)=>a
类型
类型a
其中类型是“联合类型”,例如
Val
ExprTree

现在,我想通过添加几个实例使我的数据类型
ExprTree
更加通用:

import Ratio
data Fun = Add|Sub|Mul|Div|Pow
    deriving (Eq,Ord)
instance Show Fun where
    show Add = "+"
    show Sub = "-"
    show Mul = "*"
    show Div = "/"
    show Pow = "^"
type Label = Rational
type Var = String
class Eval e where
eval :: (Num a) => e -> a -> a
data ExprTree a = Leaf {lab::Label, val::Val a}
          | Node {lab::Label, fun::Fun, lBranch::ExprTree a, rBranch::ExprTree a}
          deriving(Eq,Ord)
data Val a = Num a | Var String deriving (Eq, Ord, Show)

instance(Num a)=>Num(ExprTree a)其中
...

fromInteger i=Leaf(0%1)i--实例定义
Num
的问题是您说您正在显示 任何
ExprTree
都是
Num
(表示任何类型
a
)的一个实例,但是 您展示了
exprtreeinteger
是Num的一个实例。换句话说,您不能 如果不想像这样声明实例,请专门化该类型变量 这:

Show实例也有类似的问题。你没有展示你是怎么做的
exprtreea
是任何任意
a
的Show实例,您正在显示它 仅适用于已经是Show实例的
a
s。换句话说,你会 需要更改实例声明,如下所示:

instance (Show a) => Show (ExprTree a) where
     ...
为了让它工作

Eval实例声明中的第三个错误来自一些无关的东西 很普通,基本上你是在使用a->e->e类型的函数 您正在返回第一个参数
a
。Haskell很困惑,因为你 鉴于没有迹象表明
a
e
是同一类型,因此没有理由 它应该接受
a
类型的值作为返回类型。(这可能只是一个例子 你可能会有点困惑。
eval
有签名(nume)=>e->a-> a、 但是您已经在实例声明中将第一个变量命名为
a
Val a

所以,排除第三审声明,你的问题似乎是 向Haskell承诺,您将为 非常通用的类型(如任何
a
都使用
exprtreea
),但随后您就违背了
通过要求
a
是某种更具体的类型,如
Integer

来保证
fromInteger
的问题是
i
需要转换为
Val a

instance Num a => Num (ExprTree a) where
    -- ...
    fromInteger i = Leaf (0%1) (Val (fromInteger i))
Val
包装器使其成为
Val
;内部
fromInteger
创建一个
a
,这是调用方指定的类型,我们知道可以使用
fromInteger
创建该类型,因为
Num a
约束来自
Integer
。请密切注意最后一点:这是类型类背后的原因。
Num a=>
约束确保,给定
a
,我们知道可以对其使用任何
Num
实例方法

另一个问题与此相反:您正在调用
show
,但是您没有做任何事情来确保
show
a
上有意义

instance Num a => Num (ExprTree a) where
    -- ...
    fromInteger i = Leaf (0%1) (Val (fromInteger i))
instance Show a => ExprTree a where
    show (Leaf _ a) = show a -- this works now because we told it a is show-able
    -- ...

Eval
的问题略有不同:
a
只是在没有任何源代码的情况下出现,因此编译器对它一无所知。特别是,
eval a\ua
要求
e
必须是有效的
a
——但是
a
是未知的,因此编译器正确地说“什么?”。对于这一点,你需要考虑你真正想要做什么;最简单的解决方案是去掉
e
并在任何地方使用
a
,但这真的是你想要的吗?

我不认为那种
eval
是你想要的。它太笼统了,因为它承诺对任何
a
都有效,只要它在
Num
中。
instance Show a => ExprTree a where
    show (Leaf _ a) = show a -- this works now because we told it a is show-able
    -- ...