簡體   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