Code Whisperer
Code Whisperer

Reputation: 23662

PureScript - How to Add or Subtract NewTypes

Consider this intuitive example, where one attempts to use the (+) operator on two NewTypes derived from Number:

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

However, attempting this operation produces the following error:

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

So, in essense, the question is

How do you operate on newtypes as though they were the type they were derived from?

So ideally this solution would also work when concatenating two values of a new type based on string, or comparing two values of a new type based on boolean, etc.

Upvotes: 0

Views: 76

Answers (1)

Dogbert
Dogbert

Reputation: 222388

newtypes do not inherit the typeclass implementations of the underlying type. You either have to implement it manually, or if it's supported, derive the instance. In this case, PureScript supports deriving addition (Data.Semiring):

newtype Balance = Balance Number

derive newtype instance Semiring Balance

Full code (you can copy paste it into https://try.purescript.org/ to try):

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))

Output:

23.68

Upvotes: 2

Related Questions