This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Re: Re: simulating call-by-name with case classes?

No replies
ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
That's just what I was going to suggest, but I was also going to ask if you really wanted to have a Function0 as a parameter in a case class.  That isn't going to do you much good for pattern matching, toStringing, or anything else that case classes do for you.

Wouldn't you be better off with a boxed lazy val?

class LazyBox[T](ft: => T) {
  private[this] lazy val t = ft
  def unbox = t
  override def toString = t.toString
  override def hashCode = t.hashCode
}
implicit def unbox_boxer[T](b: LazyBox[T]) = b.unbox

  --Rex

On Sun, Dec 4, 2011 at 9:53 AM, Ittay Dror <ittay [dot] dror [at] gmail [dot] com> wrote:



Ittay Dror wrote:

I want a case class to have a call-by-name argument to its constructor. 

scala> case class Foo(s: => String)
<console>:1: error: `val' parameters may not be call-by-name
       case class Foo(s: => String)

ok, so I try creating an apply method in the companion object:
scala> :paste
// Entering paste mode (ctrl-D to finish)

case class Foo(s: () => String)
object Foo {def apply(s: => String) = new Foo(() => s)}

// Exiting paste mode, now interpreting.

<console>:7: error: double definition:
method apply:(s: () => String)Foo and
method apply:(s: => String)Foo at line 8
have same type after erasure: (s: Function0)$line2.$read#$iw#$iw#Foo
       case class Foo(s: () => String)
                  ^

Of course I can create a regular class, but the class I'm writing is really a value class. Is there another way to achieve what I want?

My current workaround is to use an implicit argument with a default value of null to disambiguate. Any nicer alternatives?


Regards,
Ittay

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland