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 Strings 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