Using iron as a newtype #124
Replies: 3 comments 5 replies
-
Ok, actually after a bit more research it doesn't work because my |
Beta Was this translation helpful? Give feedback.
-
@chuwy Is this problem:
Solved? If you use these types in a different file than their declaration, they should not be mixed if they're opaques.
I think it is viable and we're working on it. See #125 |
Beta Was this translation helpful? Give feedback.
-
Hi @Iltotore! No, I haven't really solved that. Let me explain the problem more clearly: type Newtype = True DescribedAs "Just a newtype"
type PersonId = UUID :| Newtype
type PetId = UUID :| Newtype The case class Item(id: UUID, name: String) // plain UUID
case class Person(id: PersonId, name: String) // Newtype
case class Pet(id: PetId, name: String) // Newtype
val init = Item(UUID.randomUUID, "Foo")
// This doesn't work without refine and that's cool
Person(item.id, item.name)
// But unfortunately, this works
val person = Person(UUID.randomUUID.refine, "Foo")
Pet(person.id, person.name) So, in a nutshell the problem is that we narrow UUID (i.e. I see two potential ways of solving this (IMO crucial) problem. First is to stick to opaque types, which is what I wanted to get away from. Another is introduce some kind of tags: type PersonId = UUID :| Newtype["person"]
type PetId = UUID :| Newtype["pet"] I'll try to play with these tags once I get to Iron again, but I kind of don't like the fact that it needs a boilerplate. |
Beta Was this translation helpful? Give feedback.
-
I was so excited when first found out about opaque types in Scala 3. I thought we'd be able to use them as Haskell newtype 1:1 replacement. But they're not newtypes - typechecker doesn't really distinguish
Int
fromopaque type Foo = Int
(scala/scala3#17211). There are few more problems that I don't want to dive deeper, but long story short - I'd recommend to not use opaque types in an app (lib is fine if all aspects are understood) codebase.As a result we have separate libs for newtypes: Monix newtypes and ZIO Prelude Newtype.
Iron's (or any other refined types lib) usecase look somewhat orthogonal, but in fact I think it's a superset of what newtypes provide. Newtypes provide a way to restrict an arbitrary type without adding restrictions and Iron does the same with adding restrictions, but usually with specific types like
String
,Int
,List
.However, I think that by defining a generic
Newtype
constraint we get the typical newtype pattern without using any special lib....which is IMO cool because it's the same API for constrained and unconstrained type and getting all the benefits, like auto-derived codecs etc.
What do you reckon? Is it a viable approach?
Beta Was this translation helpful? Give feedback.
All reactions