You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently it's somewhat hard to bind functions with implicit parameters using ModuleDefDSL. We can't bind them like ordinary functions:
finalcaseclassDescription[T](description: String)
finalcaseclassX(s: String)
defmakeX()(implicitdesc: Description[X]):X=newX(desc.description)
objectmoduleextendsModuleDef {
make[Description[X]].fromValue(Description("X"))
make[X].from(makeX _) // error: no implicit value Description[X]
}
Because implicit parameters are resolved eagerly the moment we refer to the function value makeX _ - they are not part of the type signature of the function value: val f: () => X = makeX _ // no Description[X] parameter. The two ways to work around this currently are to:
pass the implicit parameters explicitly:
make[X].from((d: Description[X]) => makeX()(d))
And (preferred) to wrap the function into a class and use automatic class construction feature of the DSL:
This is the main use case of helper classes Lifecycle.LiftF and Lifecycle.Of - to create class-based wrappers for functions that require implicit parameters (such as typeclass instances), to workaround the limitation of Scala 2 that implicit functions are unrepresentable - to improve ergonomics of adding them to the object graph.
Scala 3
However, Scala 3 now makes implicit functions representable which could allow us to solve this problem directly. Unfortunately the easiest way to support this - using overloading - doesn't work - lampepfl/dotty-feature-requests#150, but perhaps we could implement this using a macro - using a signature like def from[I <: T](f: Nothing ?=> Functoid[I]): AfterFrom to obtain a tree such as (nothing: Nothing) ?=> makeX()(nothing) and then rewriting the tree by substituting the Nothing placeholder with the correct types for arguments taken out of makeX type signature: (desc: Description[X]) => makeX()(using desc)
The text was updated successfully, but these errors were encountered:
Currently it's somewhat hard to bind functions with implicit parameters using ModuleDefDSL. We can't bind them like ordinary functions:
Because implicit parameters are resolved eagerly the moment we refer to the function value
makeX _
- they are not part of the type signature of the function value:val f: () => X = makeX _ // no Description[X] parameter
. The two ways to work around this currently are to:This is the main use case of helper classes
Lifecycle.LiftF
andLifecycle.Of
- to create class-based wrappers for functions that require implicit parameters (such as typeclass instances), to workaround the limitation of Scala 2 that implicit functions are unrepresentable - to improve ergonomics of adding them to the object graph.Scala 3
However, Scala 3 now makes implicit functions representable which could allow us to solve this problem directly. Unfortunately the easiest way to support this - using overloading - doesn't work - lampepfl/dotty-feature-requests#150, but perhaps we could implement this using a macro - using a signature like
def from[I <: T](f: Nothing ?=> Functoid[I]): AfterFrom
to obtain a tree such as(nothing: Nothing) ?=> makeX()(nothing)
and then rewriting the tree by substituting the Nothing placeholder with the correct types for arguments taken out ofmakeX
type signature:(desc: Description[X]) => makeX()(using desc)
The text was updated successfully, but these errors were encountered: