Created
October 8, 2019 14:33
-
-
Save soujiro32167/f0145b2129e2ea6cf47b14b1b6a48930 to your computer and use it in GitHub Desktop.
Limits of type inference
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
import io.circe.syntax._ | |
import io.circe._ | |
import io.circe.parser._ | |
import io.circe.generic.semiauto._ | |
import scalaz.NonEmptyList | |
sealed trait TType { | |
type Self | |
} | |
object TType { | |
def serialize[A <: TType](value: A#Self)(implicit enc: Encoder[A#Self]): Json = value.asJson | |
def deserialize[A <: TType](value: String)(implicit dec: Decoder[A#Self]): Either[Error, A#Self] = decode[A#Self](value) | |
} | |
sealed trait FirstOrderType extends TType { | |
type Outer[_] | |
type Inner | |
override type Self = Outer[Inner] | |
} | |
case object TInt extends TType { | |
type Self = Int | |
} | |
implicitly[TInt.Self =:= Int] // compiles | |
final case class TList(of: TType) extends TType { | |
type Self = List[of.Self] | |
// implicit val enc: Encoder[Self] = deriveEncoder | |
def serializeAny(any: Any)(implicit enc: Encoder[Self]): Json = any.asInstanceOf[Self].asJson | |
} | |
val fot = TList(TInt) | |
//implicitly[fot.of.Self =:= Int] // cannot prove that | |
//implicitly[fot.Self =:= List[Int]] // cannot prove that | |
TType.serialize[TInt.type](1) | |
//TType.serialize[fot.type](List(1)) | |
//TList(TInt).serialize(List(1)) | |
final case class TList2(of: TType) extends FirstOrderType { | |
override type Inner = of.Self | |
override type Outer[A] = List[A] | |
} | |
// | |
val fot2 = TList2(TInt) | |
implicitly[fot2.Outer[fot2.Inner] =:= List[fot2.Inner]] | |
//implicitly[fot2.Inner =:= Int] | |
//------------------------------- | |
sealed trait TTypeG[T] { | |
type Self = T | |
} | |
def serializeG[A <: TTypeG[T], T](value: T)(implicit enc: Encoder[A#Self]): Json = value.asJson | |
//def serializeG2[T <: TTypeG[T]](value: T)(implicit enc: Encoder[T]): Json = value.asJson | |
//def serializeFot[T <: FirstOrderTypeG[T]](value: T)(implicit enc: Encoder[T]): Json = value.asJson | |
def deserializeG[A <: TTypeG[T], T](value: String)(implicit dec: Decoder[A#Self]): Either[Error, A#Self] = decode[A#Self](value) | |
//def serializeG3[A <: TTypeG[T]](value: A#Self)(implicit enc: Encoder[A#Self]): Json = value.asJson | |
case object TIntG extends TTypeG[Int] | |
serializeG[TIntG.type, TIntG.Self](1) | |
sealed trait FirstOrderTypeG[O[_], T] extends TTypeG[O[T]] { | |
} | |
case class TListG[T](of: TTypeG[T]) extends FirstOrderTypeG[List, T] { | |
} | |
val fotG = TListG(TIntG) | |
implicitly[fotG.Self =:= List[Int]] | |
serializeG[fotG.type, fotG.Self](List(1)) | |
//serializeG2(List(1)) | |
deserializeG[fotG.type, fotG.Self]("[1]") | |
trait TListG2[T] extends FirstOrderTypeG[List, T] { | |
} | |
object TListG2 { | |
def apply[T]: TListG2[T] = new TListG2[T] {} | |
} | |
val fotG2 = TListG2[Int] | |
serializeG[fotG2.type, fotG2.Self](List(1)) | |
//serializeG2[fotG2.Self](List(1)) | |
deserializeG[fotG2.type, fotG2.Self]("[1]") | |
// -------------- F Type Poly ----------------------- | |
//sealed trait FOTConstrained[O[_], T] extends TTypeG[O[T]] | |
// | |
//object FOTConstrained { | |
// def apply[O[_], T <: TTypeG[T]]: FOTConstrained[O, T] = new FOTConstrained[O, T] {} | |
//} | |
// | |
//val fotC = FOTConstrained[List, TIntG.type] | |
// ------ RECORDS ------- | |
case class TRecordG(name: String, args: NonEmptyList[(String, TTypeG[_])]) extends TTypeG[TRecordG.Record] { | |
} | |
object TRecordG { | |
case class Record(name: String, values: Map[String, TTypeG[_]#Self]) | |
} | |
val recG = TRecordG("rec", NonEmptyList( | |
"i" -> TIntG, | |
"l" -> TListG(TIntG) | |
)) | |
//serializeG[recG.type, recG.Self](TRecordG.Record("rec", Map("i" -> 1, "l" -> List(1)))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment