Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/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 如何为二进制运算符定义typeclass?_Haskell - Fatal编程技术网

Haskell 如何为二进制运算符定义typeclass?

Haskell 如何为二进制运算符定义typeclass?,haskell,Haskell,这是一个只对数字求和的计算器: module Data.Calculator where data Expr = Plus Expr Expr | Value Int evaluate :: Expr -> Int evaluate (Value a) = a evaluate (Plus (Value a) (Value b)) = a + b evaluate (Plus (Plus left right) (Value b)) = (evaluate left) + (evalu

这是一个只对数字求和的计算器:

module Data.Calculator where

data Expr = Plus Expr Expr | Value Int

evaluate :: Expr -> Int
evaluate (Value a) = a
evaluate (Plus (Value a) (Value b)) = a + b
evaluate (Plus (Plus left right) (Value b)) = (evaluate left) + (evaluate right) + b
evaluate (Plus (Value a) (Plus left right)) = a + (evaluate left) + (evaluate right)
evaluate (Plus a@(Plus left right) b@(Plus left' right')) = (evaluate a) + (evaluate b)
evaluate
函数似乎很冗长。理想情况下,我希望定义一个类型类,包括两个运算符,然后将
Plus
定义为运算符的实例,如下所示:

class BinaryOp a where
    apply :: a -> a -> Expr

instance BinaryOp Plus where
    apply x y = x + y
data Expr = Plus Expr Expr | Value Int

class BinaryOp a where
    apply :: a -> a -> Int

instance BinaryOp Expr where
    apply x y = evaluate $ Plus x y
但这显然不起作用,因为定义
BinaryOp
的类型
a
是运算符,而不是操作数


如何执行此操作?

您的
evaluate
函数可以

evaluate :: Expr -> Int
evaluate (Value x) = x
evaluate (Plus x y) = evaluate x + evaluate y
因为所有的案例都被考虑在内了

对于每个类型类,您不能为
Plus
创建实例,因为这是一个构造函数,您需要为类型指定实例(在本例中,
Expr
是类型,而
Plus
Value
是构造函数)。如果您想要一个typeclass,它接受特定类型的两个元素并生成一个
Int
,您可以编写如下代码:

class BinaryOp a where
    apply :: a -> a -> Expr

instance BinaryOp Plus where
    apply x y = x + y
data Expr = Plus Expr Expr | Value Int

class BinaryOp a where
    apply :: a -> a -> Int

instance BinaryOp Expr where
    apply x y = evaluate $ Plus x y

如果
evaluate
有type
Expr->Int
,那么我认为
apply
应该是
\xy->evaluate(加上xy)
而不仅仅是
evaluate
。我认为在这里使用typeclass是个坏主意。当涉及到许多类型时,typeclass可能很有用——这里只有一种。@AlexisKing是的,你说得很对,谢谢你抓住了它!