Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala and type bound with a given operation

Tags:

scala

Is it possible to define a parameter x in a method, such that the type of x is a generic type T that implements a given function signature (let us say def apply() : Double), without introducing a new type?

[Example] The goal is to define something like (I am using an adhoc syntax just for the sake of illustration):

def foo(x : T with def apply() : Double) = { ... }

Currently, I could introduce a new type ApplyDouble, but that would require me extending all possible types whose instances are legal parameters to 'foo', and foo's signature would then be turned into

def foo(x : ApplyDouble) = { ... }

like image 386
leco Avatar asked Jul 29 '13 19:07

leco


1 Answers

Sure, it's possible with a structural type, and you've even almost got the syntax right:

def foo(x: { def apply(): Double }) = x.apply

And then:

scala> foo(() => 13.0)
res0: Double = 13.0

Or:

scala> foo(new { def apply() = 42.0 })
res1: Double = 42.0

The definition of foo will give you a warning about reflective access, which you can avoid by adding an import or compiler option (as described in the warning message).

Note that there is some overhead involved in calling methods on a structural type, so if you need this in a tight inner loop you may want to rethink your approach a bit. In most cases, though, it probably won't make a noticeable difference.

like image 61
Travis Brown Avatar answered Oct 31 '22 03:10

Travis Brown