字符串被视为 Monoid
给定这样的签名或 那个:
def foo[A, F[_]](implicit mon: Monoid[F[A]], pr: Pure[F]): F[A]
假设 A 是 Char
,有没有办法获取 String
而不是 List[Char]?
String
不接受类型参数,所以我认为这是不可能的。下一个最佳选择是什么?现在,我对结果使用 mkString
,但这感觉不是最佳的。
我认为 String
是一个具有 0 ""
和 append +
的幺半群。 。
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 +
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
可以说服 String 伪装成更高级的类型,从而允许使用
foo
形式的函数。但是,Scala 的类型推断目前无法完成推断foo
类型参数的工作,因此您必须显式提供它们,请注意
Char
类型foo
的参数未使用,可以是任何内容,但必须是某些内容:在这种情况下,Char
是自然选择,但Nothing
或 < code>Any 也可以。请注意,此解决方案利用了
String
的特殊特性:所有类型的值都可以转换为String
,因此pure[A](a : => A ) : String
对于所有类型A
都是可实现的。对于String
以外的类型复制此习惯用法很可能必须利用某种机制来在pure
主体中实现特定于类型的情况(例如某种模式匹配) )。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 inferringfoo
's type arguments, so you'll have to supply them explicitly,Note that the
Char
type argument tofoo
is unused and can be anything, but must be something: in this case eitherChar
is the natural choice, butNothing
orAny
would do as well.Note that this solution trades on
String
's special characteristics: values of all types are convertible toString
s sopure[A](a : => A) : String
is implementable for all typesA
. Replicating this idiom for types other thanString
would most likely have to exploit some mechanism for implementing type-specific cases in the body ofpure
(eg. a pattern match of some sort).我能想到的最好的解决方案是定义从
List[Char]
到String
的隐式转换。The best solution I can think of it is to define an implicit conversion from
List[Char]
toString
.根据你的分析,scala 的类型系统将拒绝 String,因为它不是“更高种类的类型”* -> * 是正确的。也就是说,对于任何 F, String 类型都不能分配给
F[_]
。您可以尝试(我没有检查这一点)隐式转换......但我怀疑这不会那么有用,因为您必须在需要时提供自己的定制转换,而且还因为假设这是代码的热门部分,性能会很糟糕。
或者,使用标准库,您可以使用
CanBuildFrom
机制,但它与 scalaz 风格类型类的混合效果如何很好还远不明显。当然,在方法主体中,您将需要使用构建器来构造返回值,而不是 Monoid/Pure 类型类,我怀疑这使得它们有些多余。
Your analysis, that scala's type-system will reject String as not being a "higher kinded type" * -> * is correct. That is, the type String is not assignable to
F[_]
for any F. You could try (I have not checked this) implicit conversions......but this will not be that useful I suspect because you'd have to provide your own bespoke conversions where required but also because the performance would be terrible, assuming this is a hot part of the code.
Or, using the standard library, you could use the
CanBuildFrom
machinery but it's far from obvious how nicely this will mix with the scalaz-style typeclasses.In the body of the method, of course, you will need to use the builder to construct the return value, as opposed to the Monoid/Pure typeclasses, rendering them somewhat redundant, I suspect.