Last active
February 3, 2026 20:22
-
-
Save dacr/dd676f8cb50fa668918109b8de617e98 to your computer and use it in GitHub Desktop.
scala3 feature examples - opaque types / published by https://github.com/dacr/code-examples-manager #f51b97ee-6fe7-4c76-bc8d-837c7eff6d9e/fc2e5a554ef23c46aacbf6323af7e8791d800639
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // summary : scala3 feature examples - opaque types | |
| // keywords : scala3, tutorial, @testable | |
| // publish : gist | |
| // authors : David Crosson | |
| // license : Apache License Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0.txt) | |
| // id : f51b97ee-6fe7-4c76-bc8d-837c7eff6d9e | |
| // created-on : 2021-03-19T17:06:38+01:00 | |
| // managed-by : https://github.com/dacr/code-examples-manager | |
| // run-with : scala-cli $file | |
| //> using scala "3.4.2" | |
| /* | |
| The perfect feature for Domain Driven Design (DDD) without overhead | |
| */ | |
| import java.util.UUID | |
| import scala.util.Try | |
| object ProjectDefinitions { | |
| // -- INSIDE OPAQUE TYPES DEFINITIONS SCOPE OPAQUE TYPE RESTRICTION DOESN'T APPLY | |
| opaque type Email = String | |
| opaque type UserId = UUID | |
| object Email { | |
| def fromString(email: String): Option[Email] = if (checkEmail(email)) Some(email) else None | |
| def checkEmail(email: String): Boolean = email.matches("""^[A-Za-z0-9+_.-]+@(.+)$""") | |
| } | |
| object UserId { | |
| def fromString(id: String): Option[UserId] = Try(UUID.fromString(id)).toOption | |
| } | |
| } | |
| @main def go() = { | |
| import ProjectDefinitions.* | |
| // -- OUTSIDE OPAQUE TYPES DEFINITIONS SCOPE OPAQUE TYPE RESTRICTION DOES APPLY SO : | |
| //val myemail:Email = "toto@truc.bidule@@" // it should fail | |
| //val e1:String = Email.fromString("toto@truc.com").get // it should fail | |
| //val e2:Email = "toto@truc.com" // it should fail | |
| Email.fromString("toto@truc.com") match { | |
| case None => println("Invalid mail") | |
| case Some(email) => println(email) | |
| } | |
| // UUID::version is invisible as type is opaque so no way to have access to its internals | |
| UserId.fromString("deadbeef-dead-cafe-dead-beefdeadcafe") match { | |
| case None => println("Invalid userId") | |
| case Some(userId) => println(userId) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment