PureScript - 如何添加或减去 NewType

PureScript - How to Add or Subtract NewTypes

考虑这个直观的示例,其中有人尝试对从 Number 派生的两个 NewTypes 使用 (+) 运算符:

module Main where

import Prelude (Unit, (+))
import Effect (Effect)
import Effect.Console (logShow)

newtype Balance = Balance Number

a :: Balance
a = Balance 7.18

b :: Balance
b = Balance 16.50

c :: Balance
c = a + b

main :: Effect Unit
main = do
  logShow c

但是,尝试此操作会产生以下错误:

No type class instance was found for
  
    Data.Semiring.Semiring Balance
  

while applying a function add
  of type Semiring t0 => t0 -> t0 -> t0
  to argument a
while inferring the type of add a
in value declaration c

where t0 is an unknown type

所以,本质上,问题是

你如何操作新类型,就好像它们是它们的派生类型一样?

理想情况下,此解决方案也适用于连接两个基于字符串的新类型值,或比较两个基于布尔值的新类型值等。

newtypes 不继承基础类型的类型类实现。您要么必须手动实施它,要么如果它受支持,derive the instance。在这种情况下,PureScript 支持派生加法 (Data.Semiring):

newtype Balance = Balance Number

derive newtype instance Semiring Balance

完整代码(你可以复制粘贴到https://try.purescript.org/中试试):

module Main where

import Prelude (Unit, (+))
import Data.Semiring (class Semiring)
import Data.Show (class Show)
import Effect (Effect)
import Effect.Console (logShow)

newtype Balance = Balance Number

derive newtype instance Semiring Balance
derive newtype instance Show Balance

main :: Effect Unit
main = do
  logShow ((Balance 7.18) + (Balance 16.50))

输出:

23.68