Given a signature like this one or that one:
def foo[A, F[_]](implicit mon: Monoid[F[A]], pr: Pure[F]): F[A]
Assuming A is Char
, is there a way to get a String
instead of a List[Char]
?
String
does not take a type parameter, so I assume it's not possible. What's the next best option? Right now, I use mkString
on the result, but that doesn't feel optimal.
I think String
is a monoid with zero ""
and append +
...
It is possible to persuade String to masquerade as a higher-kinded type, and hence allow functions of the form of foo
to be applicable. However, Scala's type inference isn't currently up to the job of inferring foo
's type arguments, so you'll have to supply them explicitly,
// Assuming the the definitions of Pure and Monoid from Scalaz
type ConstString = {
type λ[X] = String
}
implicit def StringPure = new Pure[ConstString#λ] {
def pure[A](a: => A) = a.toString
}
val sm = implicitly[Monoid[String]]
val sp = implicitly[Pure[ConstString#λ]]
val f : String = foo[Char, ConstString#λ](sm, sp) // OK
Note that the Char
type argument to foo
is unused and can be anything, but must be something: in this case either Char
is the natural choice, but Nothing
or Any
would do as well.
Note that this solution trades on String
's special characteristics: values of all types are convertible to String
s so pure[A](a : => A) : String
is implementable for all types A
. Replicating this idiom for types other than String
would most likely have to exploit some mechanism for implementing type-specific cases in the body of pure
(eg. a pattern match of some sort).
The best solution I can think of it is to define an implicit conversion from List[Char]
to String
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With