Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6813775
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T20:36:34+00:00 2026-05-26T20:36:34+00:00

I’m trying to create types Tuple equivalent to the ones in the Scala library,

  • 0

I’m trying to create types Tuple equivalent to the ones in the Scala library, only with a :+ method that extends a Tuple into a Tuple by addition of the N+1st value — so that I will be able to construct Tuples recursively:

class Test {
  abstract class Tuple {
    //protected type Next[_] <: Tuple
    //def :+[T](p: T): Next[T]
  }

  case class Tuple0() extends Tuple {
    protected type Next[T] = Tuple1[T]
    def :+[T](p: T): Next[T] = Tuple1(p)
  }

  case class Tuple1[+T1](p1: T1) extends Tuple {
    protected type Next[T] = Tuple2[T1, T]
    def :+[T](p: T): Next[T] = Tuple2(p1, p)
  }

  case class Tuple2[+T1, +T2](p1: T1, p2: T2) extends Tuple {
    protected type Next[-T] = Nothing
    def :+[T](p: T): Next[T] = throw new IndexOutOfBoundsException();
  }
}

This compiles, but as soon as I uncomment the definition of Tuple#Next, I get:

Test.scala:13: error: covariant type T1 occurs in invariant position in type [T]Test.this.Tuple2[T1,T] of type Next
    protected type Next[T] = Tuple2[T1, T]
                       ^
one error found

Why is that? Can you provide a workaround which would allow me to build Tuples (of mixed, type-safe value types) recursively?

Thanks.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T20:36:35+00:00Added an answer on May 26, 2026 at 8:36 pm

    You could do what Mark Harrah does in up:

    sealed trait HList
    
    case class HCons[+H, +T <: HList](head: H, tail: T) extends HList
    {
        def :+:[T](v : T) = HCons(v, this)
    }
    
    case object HNil extends HList
    {
        def :+:[T](v : T) = HCons(v, this)
    }
    

    That is, don’t have a type member for the next type. There may be things you can’t do like
    this… you’ll notice that up’s HList is not covariant for this reason.

    I would really like it if someone could point out a general way to make type
    members covariant. I’m afraid the reason why they are not is above my head, though it might
    have something to do with this sentence from Martin Oderksy’s paper:

    Value members
    always behave covariantly; a type member becomes invariant as
    soon as it is made concrete. This is related to the fact that Scalina
    does not admit late-binding for type members.

    Though if someone could explain that sentence to me I would be delighted 😉


    Edit: Here is another approach that is closer to what you originally asked for. On
    writing it I realized I’m not sure if this will really do what you want…
    maybe you could give an example of how you’re intending to use these tuples?

    Since we can’t have covariant type members, we can put the “next tuple” logic
    into a separate trait:

    trait Add {
        type N[T]
        type Add2[T] <: Add
    
        def add[T](x: T): N[T]
        def nextAdd[T](n: N[T]): Add2[T]
    }
    

    And then implicitly convert to it:

    class Tuple0Add extends Add  {
        type N[T1] = T1
        type Add2[T1] = Tuple1Add[T1]
    
        def add[T1](x: T1) = x
        def nextAdd[T1](n: T1) = new Tuple1Add(n)
    }
    implicit def tuple0Add(t0: Unit) = new Tuple0Add
    
    class Tuple1Add[T1](t1: T1) extends Add {
        type N[T2] = (T1, T2)
        type Add2[T2] = Nothing
    
        def add[T2](x: T2) = (t1, x)
        def nextAdd[T2](n: (T1,T2)) = sys.error("Can't go this far")
    }
    implicit def tuple1Add[T1](t1: T1) = new Tuple1Add(t1)
    

    This is a general technique I have found useful: Scala doesn’t complain if you
    implicitly convert a covariant type to an invariant type.

    This then allows you to do 2 things above what you could do with regular tuples:

    1) Build a tuple manually in steps, and preserve type information:

    > val a = () add 1 add 2
    > a._1
    1
    > a._2
    2
    

    2) Build a tuple dynamically and, sadly, lose type information:

    def addAll(a: Add, s: List[_]): Any = s match {
        case Nil    => a
        case x::Nil => a add x
        case x::xs  => addAll(a.nextAdd(a add x), xs)
    }
    
    > addAll((), List(1, 2))
    (1, 2)
    

    What we really would have liked to do
    would be to have written

    trait Add {
        type N[T] <% Add
    
        def add[T](x: T): N[T]
    }
    

    That is, ensure that after adding 1 element, the result can then have more
    things added to it; otherwise we could not build tuples dynamically.
    Unfortunately, Scala does not accept view bounds on type members. Luckily, a
    view bound is nothing more than a method that does the conversion; so all we
    have to do is manually specify the method; hence nextAdd.

    This may not be what you are looking for, but maybe it will give you some ideas
    how to get closer to your actual goal.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to create an if statement in PHP that prevents a single post
Basically, what I'm trying to create is a page of div tags, each has
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have a French site that I want to parse, but am running into
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I am trying to understand how to use SyndicationItem to display feed which is
That's pretty much it. I'm using Nokogiri to scrape a web page what has
this is what i have right now Drawing an RSS feed into the php,
I've got a string that has curly quotes in it. I'd like to replace
I want use html5's new tag to play a wav file (currently only supported

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.