Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessing underlying value of opaque-based iron type #121

Closed
antonkw opened this issue May 22, 2023 · 3 comments · Fixed by #120
Closed

Accessing underlying value of opaque-based iron type #121

antonkw opened this issue May 22, 2023 · 3 comments · Fixed by #120
Labels
enhancement New feature or request

Comments

@antonkw
Copy link
Contributor

antonkw commented May 22, 2023

As far as I see, many people consider opaque types as something they can use in the same way as newtypes.
That connotation of domain values maintenance implies having access to underlying value.

Access to underlying values is another step to let Iron be a legitimate replacement of the newtype+refined stack.

opaque type Temperature = Double :| Positive
object Temperature extends RefinedTypeOps[Temperature] 

Usage

val temperature = Temperature(100)
val sum: Double = temperature.raw + 100

sum is Double; depending on the context, it could be packed back to Temperature. But that is up to the user.

Pull request with the idea: #120

@antonkw antonkw added the enhancement New feature or request label May 22, 2023
@Iltotore
Copy link
Owner

Iltotore commented May 22, 2023

Scala 3 's opaque types already allow you to do it :

//The parentheses may not be mandatory
opaque type Temperature <: (Double :| Positive) = Double :| Positive
object Temperature extends RefinedTypeOps[Temperature]
val a: Temperature = Temperature(10)
val b: Double :| Positive = a //Works
val c: Double = a //Also works
val d: Double = a + 100 //110

Does it fulfill the expressed need ?

@antonkw
Copy link
Contributor Author

antonkw commented May 22, 2023

Thank you for response!

Two points there

  1. <: (Double :| Positive)-like additions are quite cumbersome
  2. additional "widening" makes it very unsafe and let opaque types behave like usual ones:
opaque type Moisture <: (Int :| Positive)  = Int :| Positive
object Moisture extends RefinedTypeOps[Moisture]

opaque type Moisture2 <: (Int :| Positive)  = Int :| Positive
object Moisture2 extends RefinedTypeOps[Moisture2]

and then

val mst: Moisture = Moisture(200)
val mst2: Moisture2 = Moisture2(200)
val sum: Int = mst2 + mst

Am I missing something?
Explicit conscious accessing still makes sense to me.

@Iltotore
Copy link
Owner

I get your point. I will take a look at your PR during the week.

@Iltotore Iltotore linked a pull request May 26, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants