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