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 7629745
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T05:54:53+00:00 2026-05-31T05:54:53+00:00

Given a tuple with elements of type A and another type parametrised in A

  • 0

Given a tuple with elements of type A and another type parametrised in A:

trait Writer[-A] { def write(a: A): Unit }
case class Write[A](value: A, writer: Writer[A])

And a use site:

trait Cache { def store[A](value: A, writer: Writer[A]): Unit }

Why does the following work as expected, using the tuple’s extractor:

def test1(set: Set[Write[_]], cache: Cache): Unit =
  set.foreach {
    case Write(value, writer) => cache.store(value, writer)
  }

But the following fails:

def test2(set: Set[Write[_]], cache: Cache ): Unit =
  set.foreach { write =>
    cache.store(write.value, write.writer)
  }

with error message

 found   : Writer[_$1] where type _$1
 required: Writer[Any]
             cache.store(write.value, write.writer)
                                        ^

Can I fix the second form (test2) to compile properly?

EDIT

Departing from the ideas by Owen I tried out if I can make it work without pattern matching at all (which is what I wanted in the first place). Here are two more strange cases, one working, the other not:

// does not work
def test3(set: Set[Write[_]], cache: Cache): Unit = {
  def process[A](write: Write[A]): Unit =
    cache.store(write.value, write.writer)

  set.foreach(process)
}

// _does work_
def test4(set: Set[Write[_]], cache: Cache): Unit = {
  def process[A](write: Write[A]): Unit =
    cache.store(write.value, write.writer)

  set.foreach(w => process(w))
}

Still pretty obscure to me…

  • 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-31T05:54:54+00:00Added an answer on May 31, 2026 at 5:54 am

    Running with -Xprint:typer is illuminating here. The problem with test2 is
    that there is an existential type, which appears in two separate places: both
    write.value and write.writer have an existential type, but, crucially, the
    compiler has no way of knowing that they have the same existentially
    quantified type variable. Even though you access them from the same object, the
    compiler forgets they came from the same place.

    When test1 is fully typed, you see:

    def test1(set: Set[Write[_]], cache: Cache) =
        set.foreach(((x0$1: Write[_]) => x0$1 match {
          case (value: _$1, writer: Writer[_$1])Write[_$1]((value @ _), (writer @ _)) =>
              cache.store[_$1](value, writer)
        }));
    

    The type variable _$1 is matched along with the values. Matching the type variable _$1 binds it in
    the scope of the case, so it’s not existential anymore, and Scala can tell
    that value and writer have the same type parameter.

    The solution for test2 is to not use existentials:

    def test2[A]( set: Set[ Write[ A ]], cache: Cache ) {
       set.foreach { write =>
          cache.store( write.value, write.writer )
       }
    }
    

    or to bind the type variable with a match:

    def test2( set: Set[ Write[ _ ]], cache: Cache ) {
       set.foreach { case write: Write[a] =>
          cache.store( write.value, write.writer )
       }
    }
    

    edit

    Let me endeavor to answer the new questions you brought up.

    The reason test3 does not work, is that when you write:

    set.foreach( process )

    process, which is polymorphic, has to be made monomorphic, for two reasons (that I know of):

    1. Functions in Scala cannot be polymorphic; only methods can be. process as defined as a method; when used as a first-class function, it is a function.

    2. The way the compiler does type inference is mostly by taking polymorphic values and unifying them together to make them less polymorphic. Passing an actual polymorphic value as a method argument would require higher-rank types.

    The reason that test4 does work is that the function literal:

    set.foreach( w => process( w ))
    

    is actually not a polymorphic function! It takes as its argument an exestentially qualified type; but not a polymorphic type. It then calls the method (not the function) process, and matches the existential type variable to process‘s type parameter. Pretty wild, eh?

    You could also write:

    set.foreach( process(_) )
    

    which, creating an anonymous function, means the same thing.

    Another route you may or may not find appropriate would be to discard
    existential types and use type members:

    trait Writable {
        type A
        val value: A
        val writer: Writer[A]
    }
    
    case class Write[T]( value: T, writer: Writer[ T ]) extends Writable {
        type A = T
    }
    
    def test2( set: Set[Writable], cache: Cache ) {
        set.foreach { write =>
            cache.store( write.value, write.writer )
        }
    }
    

    Here Scala is able to see that write.value and write.writer have the same
    type parameter because they have the same path dependent type.

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

Sidebar

Related Questions

I've made a small function which, given a tuple, compares if all elements in
Given a tuple of type (Int, a) such as (n,c) , I wish to
How do I get a tuple/list element given a condition in python? This occurs
Given a tuple (specifically, a functions varargs), I want to prepend a list containing
The Python datetime.isocalendar() method returns a tuple (ISO_year, ISO_week_number, ISO_weekday) for the given datetime
Given a specific DateTime value, how do I display relative time, like: 2 hours
So, given then following code type MyClass () = let items = Dictionary<string,int>() do
I have a tuple that i wanna store its elements, I'm trying to insert
Given definitions: typedef typename boost::graph_traits::adjacency_iterator adjacency_iter; typedef typename boost::inv_adjacency_iterator_generator::type inv_adjacency_iter; I am interested in
lst = [(32,(4,5)),(55,(5,6))] Given a tuple (4,5), so I want to remove the first

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.