Craig Treptow
Craig Treptow

Reputation: 846

Using `newtype` to wrap other types

I'm trying to understand newtype and thought this would work:

module NT where

newtype X = X Double
newtype Y = Y Double

doit :: X -> Y -> Double
doit x y = x + y

x = X 1.1
y = Y 2.2

-- doit x y should work
-- doit y x should error

The first error produced is:

NT.hs:7:12: error:
    • Couldn't match expected type ‘Double’ with actual type ‘X’
    • In the expression: X x + Y y
      In an equation for ‘doit’: doit x y = X x + Y y
  |
7 | doit x y = X x + Y y
  |

I get that the types don't match, I just don't understand how to get around it. I thought wrapping Double like this could be used to prevent the mixup of x and y in doit.

Is this true, or am I misunderstanding?

Upvotes: 2

Views: 182

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477853

You unwrap the elements out of the data constructor with pattern matching:

doit :: X -> Y -> Double
doit (X x) (Y y) = x + y

Here the x and y are thus Doubles, since the parameters the X and Y data constructor wrap are Doubles as well.

Upvotes: 4

Dietrich Epp
Dietrich Epp

Reputation: 213847

You need to “unwrap” the newtype before + can work.

doit :: X -> Y -> Double
doit (X x) (Y y) = x + y

Here, I am using pattern matching to unwrap the Double inside each argument. Here, x and y are both Double, so you can just add them with x + y.

Upvotes: 7

Related Questions