case class Foo(thunk: () => String)
def apply(str: => String): Foo = new Foo(() => str)
@main def test() =
val f = Foo("bar")
However, I wonder if I’m missing something cleaner (i.e., without the annotation). I want class Foo to be a case class for pattern-matching; I also want users to not see the thunk and use a by-name argument instead. Without the annotation, there’s a conflict between my apply method and the one that’s automatically available for case classes.
And I don’t really get why you would want to do it this way.
Basically () => String is just another why of specifying a by-value argument. So, you have double indirection there (calling thunk will evaluate (ie. call) the by-value argument each time)
Also, pattern matching on the thunk will probably not work anyway, does it? (I mean you cannot compare the thunk function in any meaningful way, apart from checking object identity) So, pattern matching is just useful for extracting the thunk from the case class.
Maybe you oversimplified your case too much and there is a deeper reason to this…?
I want to pass the argument by name because it’s cleaner on the calling site, but I also need to store it unevaluated. I don’t have access to the hidden thunk, do I? (I could use a by-name constructor argument, but only if I don’t use a case class.) Also, pattern-matching comes into play because there are other classes involved, so it’s only to distinguish Foo from other types, not between different instances of Foo.
Thanks for all the suggestions, both “clean” and “trick-based”.
such that the by-value parameter does not participate in pattern matching. I am just wondering what happens if you pass a by-value parameter by value again, if you wanted to provide a convenience factory method:
def apply(s: => String) = Foo()(s)
Oh no, this does not work:
def apply()(v: => String): Foo in object Foo at line 5 and
def apply(v: => String): Foo in object Foo at line 8
have the same type after erasure.
Consider adding a @targetName annotation to one of the conflicting definitions