我目前正在将一些代码从传统的Scala移植到Scalaz样式。
在我的大部分代码中,在公开的API签名中使用Seq特性是相当常见的,而不是直接使用具体类型(即列表、向量)。但是,这给Scalaz带来了一些问题,因为它没有提供BindSeq类型的实现。
也就是说,这将是正确的。
List(1,2,3,4) >>= bindOperation但这不会
Seq(1,2,3,4) >>= bindOperation错误could not find implicit value for parameter F0: scalaz.Bind[Seq]失败
我认为这是Scalaz中的一个有意的设计决策--但是,我不确定如何先于预期/最佳实践。
我是否应该酌情直接将代码写入List/Vector,而不是使用更灵活的Seq接口呢?或者我应该简单地定义我自己的BindSeq类型?
发布于 2014-07-15 11:58:52
集合库进行回放以适应子类型:当您在特定的集合类型(列表、地图等)上使用map时,您(通常)会得到相同的类型。它通过使用极其复杂的继承层次结构和类型类(如CanBuildFrom )来管理这一点。它完成了任务(至少可以说是这样),但复杂性并不是很有原则。真是一团糟。很多人讨厌它。
作为库用户,复杂性通常是很容易避免的,但对于库设计人员来说,这是一场噩梦。如果我为Seq提供了一个monad实例,这意味着我的所有用户的类型都会在使用一元操作的每个类型上跳到Seq。
无论如何,Scalaz的人们不太喜欢子类型,所以大多数情况下,Scalaz停留在层次结构的叶子上--List、Vector等等。例如,您可以看到一些关于这个决定的讨论( 在邮寄名单上 )。
当我第一次开始使用Scalaz时,我编写了许多实用程序代码,这些代码试图为Seq等提供实例,并使它们在CanBuildFrom中可用。然后我停止了,现在我倾向于只在我自己的代码中使用List、Vector、Map和Set来跟踪Scalaz。如果您致力于"Scalaz样式“,您也应该这样做(甚至采用Scalaz自己的IList、ISet、==>>等)。但是,您不会在更一般的最佳实践上找到明确的一致意见,而且这两种方法都可以工作,因此您只需要进行实验就可以找到您喜欢的方法。
https://stackoverflow.com/questions/24753526
复制相似问题