我最近遇到了类似于以下内容的代码。
我要问的问题是,被案例类扩展时指定的Second的类型参数(即第一个类型参数)的可能目的是什么。
我不认为使用A
,Option[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]
答案 0 :(得分:1)
遵循逻辑
我的意思是,类型参数
A
,Option[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]
,您需要一个A
和Pair[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]
,您需要对象类型B
和ThirdC[A, B]
,但您可以直接通过ThirdA[Seq[A], B]
和Class[Seq[A]]
获得B
。
例如,您可以匹配ThirdC[A, B]
,Class[A]
,B
并根据类型编写一些逻辑。因此,您可以为ThirdA
和ThirdB
指定常规逻辑。
实际上,这取决于ThirdC
,Option
,Seq
是什么。