Here's an ADT which is not a GADT, in Haskell:
data Expr = IntExpr Int | BoolExpr Bool
{-# LANGUAGE RankNTypes, TypeApplications #-} | |
-- We give a constructive proof that any natural transformation that uses | |
-- a type switch in its implementation can also be implemented without the type switch, | |
-- as long as the domain functor is finitely Traversable (and the argument can easily | |
-- be modified to drop the finiteness property). | |
-- We do this by providing a function `opaquify` which takes an n.t. which may do | |
-- type switches, and returns an equivalent n.t. which does not. |
import scala.reflect.ClassTag | |
object DefaultType extends App { | |
case class AttributeMeasure[T](name: String)(implicit ev: reflect.ClassTag[T]) { | |
def ct: ClassTag[T] = ev | |
} | |
/** This almost works, except for the case: | |
* {{{ |
import scala.reflect.ClassTag | |
object Bottom extends App { | |
class C[T](implicit ev: reflect.ClassTag[T]) { | |
def ct: reflect.ClassTag[T] = ev | |
} | |
class X[U, -T] | |
object X { |
import shapeless.{HList, HNil, ::} | |
import shapeless.ops.hlist.{Selector, Prepend} | |
import shapeless.test.illTyped | |
object TypeLevelBacktrack extends App { | |
/** [[Parent]] / [[Child]] relationship, father side. */ | |
trait FatherOf[Parent, Child] | |
/** [[Parent]] / [[Child]] relationship, mother side */ | |
trait MotherOf[Parent, Child] |
This document aims to show and compare three alternatives for achieving polymorphism in Scala.
Additionally, when implementing the typeclass pattern in Scala,