【问题标题】:Scalaz Bind[Seq] typeclassScalaz Bind[Seq] 类型类
【发布时间】:2014-07-15 08:38:25
【问题描述】:

我目前正在将一些代码从传统 Scala 移植到 Scalaz 风格。

在我的大部分代码中,在公开的 API 签名中使用 Seq 特征而不是直接使用具体类型(即 List、Vector)是相当普遍的。然而,这给 Scalaz 带来了一些问题,因为它不提供 Bind[Seq] 类型类的实现。

即这将正常工作。

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 接口?还是我应该简单地定义我自己的 Bind[Seq] 类型类?

【问题讨论】:

  • 不过有一个 IndexedSeq 的 monad 实例。

标签: scala monads typeclass scalaz


【解决方案1】:

集合库执行后空翻以适应子类型化:当您在特定集合类型(列表、地图等)上使用map 时,您(通常)会得到相同的类型。它通过使用an extremely complex inheritance hierarchy 以及像CanBuildFrom 这样的类型类来管理它。它完成了工作(至少可以说是),但复杂性感觉不是很有原则。一团糟。很多人讨厌它。

对于图书馆用户来说,这种复杂性通常很容易避免,但对于图书馆设计师来说,这是一场噩梦。如果我为 Seq 提供一个 monad 实例,这意味着我的所有用户类型都会在层次结构中向上提升到 Seq,他们使用单子操作的每种类型。

Scalaz 的人往往不太喜欢子类型化,无论如何,所以在大多数情况下,Scalaz 停留在层次结构的叶子周围——ListVector 等。你可以看到一些关于这个决定的讨论 on the mailing list ,例如。

当我第一次开始使用 Scalaz 时,我编写了许多实用程序代码,试图为 Seq 等提供实例,并使它们可用于 CanBuildFrom。然后我停了下来,现在我倾向于只在我自己的代码中使用 ListVectorMapSet 来关注 Scalaz。如果你致力于“Scalaz 风格”,你也应该这样做(或者甚至采用 Scalaz 自己的IListISet==>> 等)。但是,您不会更普遍地就最佳实践达成明确的一致意见,而且这两种方法都可以发挥作用,因此您只需进行试验以找到您喜欢的方法。

【讨论】:

  • 这也是原因吗? scalaz.NonEmptyList[T] 不是 Seq[T] 的子类型?
  • @rightfold:是的,如果有一天NonEmptyList 变得不变,我也不会太惊讶,这是不陷入Seq 沼泽的另一个原因。
猜你喜欢
  • 1970-01-01
  • 2016-08-08
  • 1970-01-01
  • 2016-04-26
  • 2018-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多