I think you’re talking about two different things. Your last example is not related to the example that you link in the SO question. Let’s tackle the discrepancy first.
sumFunc
with no type parameters is inferred to be Nothing
and then the implicit search is triggered for whatever type you’re looking for, in this case Holder
. If the implicit Holder[Nothing]
did not exist in your example, then sumFunc
with no type parameter would fail, as shown by the following REPL session:
➜ Code scala
Welcome to Scala 2.12.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_172).
Type in expressions for evaluation. Or try :help.
scala> class Holder[T]
defined class Holder
scala> def sumFunc[T: Holder]: T = ???
sumFunc: [T](implicit evidence$1: Holder[T])T
scala> sumFunc
<console>:13: error: could not find implicit value for evidence parameter of type Holder[T]
sumFunc
^
When you add implicit def holderNothing: Holder[Nothing] = ???
and try again, sumFunc
succeeds because it’s inferred to be sumFunc[Nothing]
and there exists an implicit Holder[Nothing]
.
So, coming back to your initial example with Form
and TypeTag
(which I haven’t fully understood, but I’ll use the example in the SO question as a reference), what you seem to want is to avoid a definition type to be inferred to Nothing
. For example, in val person = find("Joe")
, person
is typed as Nothing
because the type in find
is not set at the call-site and the return type is the same polymorphic type T
, with no further type restrictions. This is the expected behavior of the code.
The Scala way of avoiding Nothing
to be inferred is to create your own type class and then restrict the return type the function will return by using implicits at the definition site of find
(or sumFunc
in your previous case). So long as you don’t define the implicit for Nothing
, the code find("Joe")
will fail to compile if you implement something like the answer in the SO question.