Question

I have some types that are based on shapeless HLists:

type t1 = Int :: String :: Int :: HNil
type t2 = String :: String :: Int :: HNil

I would like to define a sealed trait ST that is a super type to all of them so that, if I have the following function:

def fun(x:ST) = …

the following are valid:

fun(5 :: "foo" :: 3 :: HNil)       // It is a t1
fun("foo" :: "bar" :: 42 :: HNil)  // It is a t2

but the following does not compile:

fun(5 :: 3 :: HNil)

How can I define t1 and t2 as subtypes of ST?

UPDATE

I think Coproducts may be a solution

type ST = t1 :+: t2 :+: CNil

fun(Coproduct[ST](5 :: "foo" :: 3 :: HNil)) // compiles
fun(Coproduct[ST](5 :: 3 :: HNil))          // does not compile
Was it helpful?

Solution

It's not possible to "make" a type into a subtype of anything using an alias, which is just a new name. While you could use a coproduct, it might be more natural just to create a new type class:

import shapeless._

type t1 = Int :: String :: Int :: HNil
type t2 = String :: String :: Int :: HNil

trait Funnable[A]

implicit object t1Funnable extends Funnable[t1]
implicit object t2Funnable extends Funnable[t2]

def fun[A: Funnable](x: A) = x

Now the lines you want to compile will, and the one you don't won't.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top