【问题标题】:Why does not sequence work with List of Validations为什么序列不适用于验证列表
【发布时间】:2015-06-24 06:23:52
【问题描述】:

我想我明白sequence 是什么。我想知道为什么它不适用于List[ValidationNel]。例如:

sequence 可与List[Option]] 完美搭配

scala> val os = List(1.some, 2.some)
os: List[Option[Int]] = List(Some(1), Some(2))

scala> os.sequence
res10: Option[List[Int]] = Some(List(1, 2))

...但不适用于List[ValidationNel]

scala> val vs: List[ValidationNel[String, Int]] = List(Success(1), Success(2))
vs: List[scalaz.ValidationNel[String,Int]] = List(Success(1), Success(2))

scala> vs.sequence
<console>:15: error: could not find implicit value for parameter ev:scalaz.Leibniz.===[scalaz.ValidationNel[String,Int],G[B]]

...但是sequenceU 确实List[ValidationNel]一起工作

scala> vs.sequenceU
res14: scalaz.Validation[scalaz.NonEmptyList[String],List[Int]] = Success(List(1, 2))

我的问题是:为什么 sequence 不能与 List[ValidationNel] 一起使用?为什么sequenceU 可以使用它?

【问题讨论】:

    标签: scala scalaz applicative traversable


    【解决方案1】:

    .sequenceU 使用 Unapply 技术来派生正确的类型,而 .sequence 则需要手动为其提供类型。

    为了让事情更烦人,sequence 的第一个类型参数需要一个类型参数,它接受一个类型参数,而不是像 ValidationNel 那样的两个。所以你要么输入 lambda it,要么做一个本地类型定义。

    试试

    type X = ValidationNel[String,X]
    
    vs.sequence[X, Int]
    

    vs.sequence[({type l[A]=ValidationNel[String,A]})#l,Int]
    

    【讨论】:

    • 太棒了!谢谢你的解释。还有一个问题:为什么sequenceList[Option] 不带任何类型参数一起工作?
    • 我不确定,但我猜 List[Option] 可以很容易地分解为正确的类型形状(即不需要类型 lambda),因此类型系统可以弄清楚它应该是什么做。
    • 我发现,.sequence 通常需要类型参数才能工作。
    • Option 是一个单参数类型。编译器知道sequence 需要一个类型参数G[_]。它可以推断Option[String] GOption,但对于ValidationNel[String, Int] 它不知道G 是什么。
    • @lmm 谢谢。所以问题是类型参数的数量。我现在看到了。
    【解决方案2】:

    不是 Scalaz 专家。

    简而言之,因为 ValidationNel 不是 monad,所以这个转换是not有效的:

    List[ValidationNel[SomeType]] => ValidationNel[List[SomeType]]

    如错误消息所示:implicit value not found,表示没有此类转换。

    【讨论】:

    • 恐怕不是真的。单子是可交换的。应用程序(那些不是单子的)- 是。
    猜你喜欢
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    • 2013-06-23
    • 1970-01-01
    相关资源
    最近更新 更多