繁体   English   中英

制作 Semigroup 的参数化数据类型实例

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM