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

  • Home
  • SEARCH
  • 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 8155963
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T16:48:58+00:00 2026-06-06T16:48:58+00:00

This is a follow-up to two questions on representation types, which are type parameters

  • 0

This is a follow-up to two questions on representation types, which are type parameters of a trait designed to represent the type underlying a bounded type member (or something like that). I’ve had success creating instances of classes, e.g ConcreteGarage, that have instances cars of bounded type members CarType.

trait Garage {
  type CarType <: Car[CarType]
  def cars: Seq[CarType]

  def copy(cars: Seq[CarType]): Garage

  def refuel(car: CarType, fuel: CarType#FuelType): Garage = copy(
    cars.map {
      case `car` => car.refuel(fuel)
      case other => other
    })
}

class ConcreteGarage[C <: Car[C]](val cars: Seq[C]) extends Garage {
  type CarType = C
  def copy(cars: Seq[C]) = new ConcreteGarage(cars)
}

trait Car[C <: Car[C]] {
  type FuelType <: Fuel
  def fuel: FuelType

  def copy(fuel: C#FuelType): C

  def refuel(fuel: C#FuelType): C = copy(fuel)
}

class Ferrari(val fuel: Benzin) extends Car[Ferrari] {
  type FuelType = Benzin
  def copy(fuel: Benzin) = new Ferrari(fuel)
}

class Mustang(val fuel: Benzin) extends Car[Mustang] {
  type FuelType = Benzin
  def copy(fuel: Benzin) = new Mustang(fuel)
}

trait Fuel
case class Benzin() extends Fuel

I can easily create instances of Cars like Ferraris and Mustangs and put them into a ConcreteGarage, as long as it’s simple:

val newFerrari = new Ferrari(Benzin())
val newMustang = new Mustang(Benzin())

val ferrariGarage = new ConcreteGarage(Seq(newFerrari))
val mustangGarage = new ConcreteGarage(Seq(newMustang))

However, if I merely return one or the other, based on a flag, and try to put the result into a garage, it fails:

val likesFord = true
val new_car = if (likesFord) newFerrari else newMustang

val switchedGarage = new ConcreteGarage(Seq(new_car)) // Fails here

The switch alone works fine, it is the call to ConcreteGarage constructor that fails with the rather mystical error:

error: inferred type arguments [this.Car[_ >: this.Ferrari with this.Mustang <: this.Car[_ >: this.Ferrari with this.Mustang <: ScalaObject]{def fuel: this.Benzin; type FuelType<: this.Benzin}]{def fuel: this.Benzin; type FuelType<: this.Benzin}] do not conform to class ConcreteGarage's type parameter bounds [C <: this.Car[C]]
val switchedGarage = new ConcreteGarage(Seq(new_car)) // Fails here
                     ^

I have tried putting those magic [C <: Car[C]] representation type parameters everywhere, but without success in finding the magic spot.

  • 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-06-06T16:48:59+00:00Added an answer on June 6, 2026 at 4:48 pm

    There aren’t any useful super types to which Ferrari and Mustang can be aliased. You need to wrap the world inside out with this approach.

    One possibility is to add the Garage construction as a method to Car.

    Another possibility is to define some ‘world’ which takes care of producing compatible cars and garages:

    trait World {
       type CarType <: Car[CarType]
       def newCar() : CarType
       def newGarage(cars: Seq[CarType]) = new ConcreteGarage[CarType](cars)
    }
    
    class FerrariWorld extends World {
       type CarType = Ferrari
       def newCar() = new Ferrari(Benzin())
    }
    
    class FordWorld extends World {
       type CarType = Mustang
       def newCar() = new Mustang(Benzin())
    }
    
    def play(world: World) {
       val car = world.newCar()
       println(car)
       val gar = world.newGarage(Seq(car))
       println(gar)
    }
    
    def test(likesFord: Boolean) {
       val w = if(likesFord) new FordWorld else new FerrariWorld
       play(w)
    }
    
    test(true)
    test(false)
    

    You can see that this can get quite claustrophobic. So it really depends on your target scenario. Path-dependent types always cause future constraints. Consider this rather simple variant with type parameters instead:

    trait Fuel { def liters: Int }
    trait Make { def color: String }
    
    case class Benzin(liters: Int = 0) extends Fuel
    case class Diesel(liters: Int = 0) extends Fuel
    case class Ferrari(color: String) extends Make
    case class Mustang(color: String) extends Make { def race() { println( "Rrrroar" )}}
    
    case class Car[M <: Make, F <: Fuel](make: M, fuel: F) {
       def refuel(f: F): Car[M, F] = copy(make, f)
    }
    
    case class Garage[M <: Make](cars: Seq[Car[M,_]] = Seq.empty) {
       def add(c: Car[M,_]) = copy(cars :+ c)
       def remove(c: Car[M,_]) = copy(cars.filterNot(_ == c))
       def refuel[F <: Fuel](c: Car[M,F], f: F) = copy( cars.map {
          case `c` => c.refuel(f)
          case other => other
       })
    }    
    
    val g0 = Garage[Mustang]()
    val m  = Car(Mustang("black"), Benzin())
    val f  = Car(Ferrari("red"), Benzin())
    val g1 = g0.add(f)                // forbidden
    val g1 = g0.add(m)                // ok
    val g2 = g1.refuel(f, Benzin(45)) // forbidden
    val g2 = g1.refuel(m, Diesel(45)) // forbidden
    val g2 = g1.refuel(m, Benzin(45)) // ok
    g2.cars.foreach(_.make.race())    // ok
    

    Conclusion: Don’t get side-tracked…

    enter image description here

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

Sidebar

Related Questions

This is a follow-up to two questions I asked a week or so back.
Sorry to follow this topic http://stackoverflow.com/questions/11044825/javascript-run-on-ie-7 I want to use document.GetElementByClassName ON INTERNET EXPLORE
i have two questions. 1, i have a input <input name=fruit type=text /> i
This is a follow-up to a previous question where I had a trait Garage
Two questions: how can I write a shell variable from this script into its
This is a follow up question . So, Java store's integers in two's-complements and
This is a follow up from Creating a class which inherits from another class
I have this follow code in my javascript. I call this function when the
I follow this tutorial online exactly but somehow it's giving me errors. Saying there
I follow this rule but some of my colleagues disagree with it and argue

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.