chaotic3quilibrium
chaotic3quilibrium

Reputation: 5934

Receiving "missing parameter type" when using underscore for input parameter on function literal

I have a trait with generic parameters which contains a method where I am attempting to define the default implementation as "empty".

trait MetaBase[T <: Throwable] {
  ...
  def riskWithEvent[V](
    vToEvaluate: => V,
    failureTEvent: FailureBase[T, V] => Unit = _ => ()
  ): TryBase[T, V] =
    ...
}

I am receiving a "missing parameter type" error at the underscore right after failureTEvent: FailureBase[T, V] => Unit =. I cannot figure out how to get the Scala compiler to let go of having to know the type information at that point as it isn't used or needed.

I considered changing the parameter to:

failureTEvent: Option[FailureBase[T, V] => Unit] = None

However, I don't like that the clients must now wrap their function in a Some(). I would much prefer to allow them to not specify the parameter, or specify the parameter without a wrapper.

Any guidance on this is greatly appreciated.

Upvotes: 0

Views: 253

Answers (1)

som-snytt
som-snytt

Reputation: 39587

Actually, it has trouble with the V param.

Here is -Ylog:typer -Ytyper-debug.

|    |    |    |    |    |-- ((x$1) => ()) : pt=FB[T,?] => Unit BYVALmode-EXPRmode (site: value g in MB) 
<console>:13: error: missing parameter type
       trait MB[T <: Throwable] { def f[V](g: FB[T, V] => Unit = _ => ()): Unit = () }
                                                                 ^
|    |    |    |    |    |    \-> <error> => Unit

Or,

scala> case class FB[T, V](t: T, v: V)
defined class FB

This works:

scala> trait MB[T <: Throwable, V] { def f(g: FB[T, V] => Unit = _ => ()): Unit = () }
defined trait MB

This doesn't:

scala> trait MB[T <: Throwable] { def f[V](g: FB[T, V] => Unit = _ => ()): Unit = () }
<console>:13: error: missing parameter type
       trait MB[T <: Throwable] { def f[V](g: FB[T, V] => Unit = _ => ()): Unit = () }
                                                                 ^

Or just take Any, since functions are contra-variant in the arg:

scala> trait MB[T <: Throwable] { def f[V](g: FB[T, V] => Unit = (_: Any) => ()): Unit = () }
defined trait MB

Other links related to default arg typing:

https://issues.scala-lang.org/browse/SI-8884

https://issues.scala-lang.org/browse/SI-7095

Scala case class.type does not take parameters

Upvotes: 3

Related Questions