0

我想让数据类型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'
4

1 回答 1

4

Moneda 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为类型 in 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 <>

因此,您仍然必须编写处理这些情况的代码。

于 2020-05-13T14:33:43.883 回答