[英]Make a parametrized data type instance of Semigroup
我想让数据类型Moneda
成为 Semigroup 的实例,并将关联操作实现为+
。 我很难正确理解它。
我找到的工作解决方案如下:
data Moneda a = RON Double | EUR Double deriving (Show)
instance Num a => Num (Moneda a) where
(RON x) + (RON y) = RON (x + y)
(RON x) + (RON y) = RON (x + y)
instance Semigroup (Moneda a) where
(<>) = (+)
我不明白为什么下面的方法会失败,以及如何在不使Moneda
成为Num
实例的情况下使其工作。
data Moneda a = RON a | EUR a deriving (Show)
instance Semigroup (Moneda a) where
(<>) (RON a) (RON b) = (RON a+b) -- fails, please see error below
vs
(<>) (RON a) (RON b) = (RON a) -- works but doesn't help me because I need the a+b sum
-- cannot construct the infinite type: a ~ Moneda a
-- In the second argument of `(+)', namely `b'
您收到的错误是因为您尝试在(<>)
的实现中将Moneda a
类型a
值添加到 a 类型的值。 那就是您编写(RON a+b)
解析为(RON a) + b
(因为函数/构造函数应用程序的绑定比加法更强)。 您可能打算这样写RON (a + b)
:
data Moneda a = RON a | EUR a deriving (Show)
instance Semigroup (Moneda a) where
(<>) (RON a) (RON b) = RON (a + b)
但这也不起作用,因为它需要在您应用Moneda
的类型上定义添加。 因此,为了使您的定义有意义,您需要将类型参数a
的实例化限制为Num
中的类型:
data Moneda a = RON a | EUR a deriving (Show)
instance Num a => Semigroup (Moneda a) where
RON a <> RON b = RON (a + b)
EUR a <> EUR b = EUR (a + b)
例如:
> RON 2 <> RON 3
RON 5
请注意, (<>)
的这个定义只是部分的。 它不考虑将使用RON
构建的值添加到使用EUR
构建的值:
> RON 5 <> EUR 7
*** Exception: Main.hs:(4,3)-(5,30): Non-exhaustive patterns in function <>
因此,您仍然必须编写处理这些情况的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.