0

I have recently come across a code that looks similar to the following.

The question I want to ask is what would be the possible purposes of the Second's type parameters(namely the first type parameter) specified when being extended by the case classes.

I do not see any particular reason to use A, Option[A] and Seq[A] as the type parameters are narrowed down by the extending case classes by [A <: SomeTrait, B <: AnotherTrait].

Am I missing any important points?

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]
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
d-_-b
  • 4,142
  • 6
  • 28
  • 43
  • I am not sure if I follows, what is the question? I do not see anything weird here. – Luis Miguel Mejía Suárez Jul 19 '19 at 02:56
  • I mean what would the type parameters `A`, `Option[A]` and `Seq[A]` be trying to achieve(enforce) here? My understanding is that using Only `A` is the same here as long as the `Second` is empty. – d-_-b Jul 19 '19 at 03:00
  • 2
    Well, it is true that you can instantiate a `ThirdA` which has a `Seq[A]` or an `Option[A]` as its A. However, thar does not means that both `ThirdB` & `ThirdC` are bad or useless. They probably exploit the fact that they know they are working on collections /optionals.to provide better implementations. – Luis Miguel Mejía Suárez Jul 19 '19 at 03:17
  • To me, the `Option[A]` or `Seq[A]` effectively does nothing from the standpoint of the extending case classes and has no enforcement on how each case class is instantiated in this particular case. – d-_-b Jul 19 '19 at 03:44
  • Yes it is not enforcing anything, but again, I do not see how that make them useless? – Luis Miguel Mejía Suárez Jul 19 '19 at 03:59
  • 2
    I don't think this question can be answered without seeing the context of how it's used. – Alexey Romanov Jul 19 '19 at 06:14
  • @AlexeyRomanov In what case do you think this can be useful? – d-_-b Jul 19 '19 at 06:30

1 Answers1

1

Following your logic

I mean what would the type parameters A, Option[A] and Seq[A] be trying to achieve(enforce) here? My understanding is that using Only A is the same here as long as the Second is empty.

this 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]

doesn't make sense because Lift[A] can be obtained as new Lam[A] {}, Pair[A, B] as new Lam[(A, B)] {}, LamC[A, B] as new Lam[A => B], App[A, B] as new Lam[B] {}, Fix[A] as new Lam[A] {}, and moreover App[X, A] is the same as Fix[A] :)

Well, yes, but objects of those types can be obtained having different objects firstly. For Lam[A] you need an A, for Pair[A, B] you need a Lam[A] and Lam[B] etc.

Similarly, yes, ThirdB[A, B] is ThirdA[Option[A], B] and ThirdC is ThirdA[Seq[A], B]. But to have objects of those types you need to have different objects firstly. In order to have ThirdA[A, B] you need objects of types Class[A] and B, in order to have ThirdB[A, B] through ThirdA[Option[A], B] you need objects of types Class[Option[A]] and B but you can have ThirdB[A, B] directly just via Class[A] and B, in order to have ThirdC[A, B] through ThirdA[Seq[A], B] you need objects of types Class[Seq[A]] and B but you can have ThirdC[A, B] directly just via Class[A] and B.

For example you can match on ThirdA, ThirdB, ThirdC and write some logic depending on type. So you can specify your general logic for Option and Seq.

So actually this depends on what SomeTrait, AnotherTrait, Class are.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66