/claim #517 /closes #517
Either is now handled properly, by transforming it into Either[String, Int] -> {Tag:“Left”,value:String}|{Tag:“Right”,value:Int}, Because union is not supported in Scala 2, we error out at compile time. Either like other sealed types are only supported in Scala 3
Scala 2 deeply nested types
case class Address(street: String)
case class Company(name: String, address: String)
case class Employee(name: String, company: Company)
val employeeTs = ToStructural.derived[Employee]
val bob = Employee("Bob", 35, Company("TechCorp", Address("123 Main St")))
val bobStruct = employeeTs.toStructural(bob)
bobStruct.name //works as expected
bobStruct.name //works as expected
bobStruct.company //works as expected
bobStruct.company.name //Fails
// The way to access deeply nested types is to cast them as Structural Record
// This is not a issue in scala3, where we can call bobStuct.company.name
val companyStruct = bobStruct.company.asInstanceOf[StructuralRecord]
companyStruct.name //works as expected
In Scala 3, for sealed types, I am confused as what is expected at runtime when values are called for, take the example below. All sealed types, (Simple Enum, Either, Sum type) are handled like below and we need to selectDynamic to view the tag or value.
sealed trait Result
case class Success(value: Int) extends Result
case class Failure(error: String) extends Result
given resultSchema: Schema[Result] = Schema.derived[Result]
val resultTs = ToStructural.derived[Result]
given ToStructural[Result] = resultTs
val resultStructSchema = summon[Schema[Result]].structural
//typename ({Tag:"Failure",error:String}|{Tag:"Success",value:Int})
val success: Result = Success(42)
val successStruct = resultTs.toStructural(success)
successStruct //val res1: resultTs.StructuralType = {value: 42, Tag: Success}
successStruct.selectDynamic("Tag")
//val res2: Any = Success
successStruct.selectDynamic("value")
//val res3: Any = 42
Is this what is expected ? or Tag is for internal representation and Typename, and expectation is successStruct = Success(value: 42)
Similarly, enum rather than having “Tag” enumStruct.selectDynamic("Tag") = "Blue" (current behavior)
should be enumStruct = Blue() ?
For Video, I am doing a simple repl showcase in Scala 2 and Scala 3. Below is the text of repl usage and outputs.
Scala 2 - https://drive.google.com/file/d/1D7bPwV7MGSvkuT7STQj2JyPDXCMr3qy5/view?usp=drive_link
import zio.blocks.schema._
case class Person(name: String, age: Int)
// Output: class Person
implicit val personSchema: Schema[Person] = Schema.derived[Person]
// Output: val personSchema: zio.blocks.schema.Schema[Person] = Schema(...)
implicit val ts = ToStructural.derived[Person]
// Warning: Implicit definition should have explicit type
// Output: val ts: zio.blocks.schema.ToStructural[Person]{
// type StructuralType = zio.blocks.schema.StructuralRecord
// } = $anon$1@1105f6af
val structuralSchema = personSchema.structural
// Output: val structuralSchema: zio.blocks.schema.Schema[ts.StructuralType] = Schema(...)
structuralSchema.reflect.typeName.name
// Output: val res1: String = {age:Int,name:String}
val alice = Person("Alice", 30)
// Output: val alice: Person = Person(Alice,30)
val aliceStruct = ts.toStructural(alice)
// Output: val aliceStruct: ts.StructuralType = {name: Alice, age: 30}|
aliceStruct.name
// Output: val res2: Any = Alice
aliceStruct.age
// Output: val res3: Any = 30
type PersonStructure = { def name: String; def age: Int }
// Output: type PersonStructure
val directSchema = Schema.derived[PersonStructure]
// Output: val directSchema: zio.blocks.schema.Schema[PersonStructure] = Schema(...)
directSchema.reflect.typeName.name
// Output: val res4: String = {age:Int,name:String}
I also do an integration test for As and Into features in the video
scala 3 - https://drive.google.com/file/d/1YGtNZwYBzxb5dx2q-H86JNFnH6rD1eQ2/view?usp=drive_link
import zio.blocks.schema._
case class Person(name: String, age: Int)
// Output: defined case class Person
given personSchema: Schema[Person] = Schema.derived[Person]
// Output: lazy val personSchema: zio.blocks.schema.Schema[Person]
val ts = ToStructural.derived[Person]
// Output: val ts:
// zio.blocks.schema.ToStructural[Person]{
// type StructuralType =
// zio.blocks.schema.StructuralRecord{val name: String; val age: Int}
// } = anon$1@51491f76
given ToStructural[Person] = ts
// Output: lazy val given_ToStructural_Person: zio.blocks.schema.ToStructural[Person]
val structuralSchema = personSchema.structural
// Output: val structuralSchema:
// zio.blocks.schema.Schema[given_ToStructural_Person.StructuralType] = Schema(...)
structuralSchema.reflect.typeName.name
// Output: val res0: String = {age:Int,name:String}
val alice = Person("Alice", 30)
// Output: val alice: Person = Person(Alice,30)
val struct = ts.toStructural(alice)
// Output: val struct: ts.StructuralType = {name: Alice, age: 30}
struct.name
// Output: val res1: String = Alice
struct.age
// Output: val res2: Int = 30
Ajay RV
@Nanashi-lab
anzal787
@anzal787
ZIO
@ZIO