Scalaz绑定[Seq]类型类
我目前正在将一些代码从传统的Scala移植到Scalaz风格 在我的大多数代码中,在我公开的API签名中使用Seq特征是相当常见的,而不是直接使用具体的类型,即列表、向量。然而,这给Scalaz带来了一些问题,因为它没有提供Bind[Seq]typeclass的实现 i、 这将正常工作Scalaz绑定[Seq]类型类,scala,monads,typeclass,scalaz,Scala,Monads,Typeclass,Scalaz,我目前正在将一些代码从传统的Scala移植到Scalaz风格 在我的大多数代码中,在我公开的API签名中使用Seq特征是相当常见的,而不是直接使用具体的类型,即列表、向量。然而,这给Scalaz带来了一些问题,因为它没有提供Bind[Seq]typeclass的实现 i、 这将正常工作 List(1,2,3,4) >>= bindOperation 但这不会 Seq(1,2,3,4) >>= bindOperation 失败,错误为找不到参数F0的隐式值:scalaz
List(1,2,3,4) >>= bindOperation
但这不会
Seq(1,2,3,4) >>= bindOperation
失败,错误为找不到参数F0的隐式值:scalaz.Bind[Seq]
我假设这是Scalaz中的一个故意设计决策-但是我不确定如何进行预期/最佳实践
我是否应该直接将代码写入List/Vector,而不是使用更灵活的Seq接口?或者我应该简单地定义我自己的Bind[Seq]类型类吗?集合库会倒扣以适应子类型:当您在特定集合类型列表、映射等上使用map时,通常会返回相同的类型。它通过与类型类(如CanBuildFrom)一起使用来管理这一点。至少可以说,它完成了任务,但其复杂性并不是很有原则。一团糟。很多人讨厌它 对于图书馆用户来说,这种复杂性通常很容易避免,但对于图书馆设计师来说,这是一场噩梦。如果我为Seq提供一个monad实例,这意味着我的所有用户类型都会在层次结构中被提升到Seq他们使用的每个类型 Scalaz的人往往不太喜欢子类型,因此Scalaz在很大程度上停留在层次结构列表、向量等的叶子上。例如,你可以看到一些关于这个决定的讨论
当我第一次开始使用Scalaz时,我编写了许多实用程序代码,试图为Seq等提供实例,并使它们可用于CanBuildFrom。然后我停了下来,现在我倾向于在我自己的代码中只使用列表、向量、映射和集合来跟随Scalaz。如果您致力于Scalaz风格,那么您也应该这样做,甚至应该采用Scalaz自己的IList、ISet、==>>等。。不过,在最佳实践方面,你不会在更普遍的情况下找到明确的一致意见,而且这两种方法都可以发挥作用,所以你只需要进行实验,找到你更喜欢的方法。不过,IndexedSeq有一个monad实例。这也是原因吗,例如scalaz。NonEmptyList[T]不是Seq[T]的子类型吗?@rightfold:是的,如果有一天非空列表变为不变量,我也不会太惊讶,这是另一个不要陷入Seq沼泽的原因。