扩展空特征时,对空特征使用类型参数的目的是什么?

时间:2019-07-19 02:15:20

标签: scala algebraic-data-types gadt

我最近遇到了类似于以下内容的代码。

我要问的问题是,被案例类扩展时指定的Second的类型参数(即第一个类型参数)的可能目的是什么。

我不认为使用AOption[A]Seq[A]的任何特殊原因,因为扩展的大小写类将类型参数的范围缩小了[A <: SomeTrait, B <: AnotherTrait]。 >

我有什么要注意的地方吗?

sealed trait Top[A, B]

sealed trait Second[A, B] extends Top[A, B]

case class ThirdA[A <: SomeTrait, B <: AnotherTrait](
  returnType: Class[A], 
  relation: B
) extends Second[A, B]

case class ThirdB[A <: SomeTrait, B <: AnotherTrait](
  returnType: Class[A],
  relation: B
) extends Second[Option[A], B]

case class ThirdC[A <: SomeTrait, B <: AnotherTrait](
  returnType: Class[A],
  relation: B
) extends Second[Seq[A], B]

1 个答案:

答案 0 :(得分:1)

遵循逻辑

  

我的意思是,类型参数AOption[A]Seq[A]将在此处试图实现(强制)什么?我的理解是,只要A为空,此处仅使用Second是相同的。

standard GADT

//  data Lam :: * -> * where
//    Lift :: a                     -> Lam a        -- ^ lifted value
//    Pair :: Lam a -> Lam b        -> Lam (a, b)   -- ^ product
//    Lam  :: (Lam a -> Lam b)      -> Lam (a -> b) -- ^ lambda abstraction
//    App  :: Lam (a -> b) -> Lam a -> Lam b        -- ^ function application
//    Fix  :: Lam (a -> a)          -> Lam a        -- ^ fixed point

  sealed trait Lam[A]
  case class Lift[A](a: A) extends Lam[A]
  case class Pair[A, B](la: Lam[A], lb: Lam[B]) extends Lam[(A, B)]
  case class LamC[A, B](f: Lam[A] => Lam[B]) extends Lam[A => B]
  case class App[A, B](f: Lam[A => B], la: Lam[A]) extends Lam[B]
  case class Fix[A](f: Lam[A => A]) extends Lam[A]

毫无意义,因为可以Lift[A]的形式获取new Lam[A] {}Pair[A, B]的形式new Lam[(A, B)] {}LamC[A, B]的{​​{1}},{{ 1}}与new Lam[A => B]App[A, B]new Lam[B] {},此外Fix[A]new Lam[A] {}相同:)

是的,但是首先可以获得具有不同对象的那些类型的对象。对于App[X, A],您需要一个Fix[A];对于Lam[A],您需要一个APair[A, B]等。

类似地,是的,Lam[A]Lam[B],而ThirdB[A, B]ThirdA[Option[A], B]。但是要拥有这些类型的对象,首先需要具有不同的对象。为了拥有ThirdC,您需要类型ThirdA[Seq[A], B]ThirdA[A, B]的对象,为了拥有Class[A]B,您需要类型{{1}的对象}和ThirdB[A, B],但您可以仅通过ThirdA[Option[A], B]Class[Option[A]]直接拥有B,为了使ThirdB[A, B]Class[A],您需要对象类型BThirdC[A, B],但您可以直接通过ThirdA[Seq[A], B]Class[Seq[A]]获得B

例如,您可以匹配ThirdC[A, B]Class[A]B并根据类型编写一些逻辑。因此,您可以为ThirdAThirdB指定常规逻辑。

实际上,这取决于ThirdCOptionSeq是什么。