4

使用 scala 作为参考,我们orElse在几个地方看到了一个后备行为 ( ),例如PartialFunctionOption和 cat EitherOps

这感觉与 monad 的扁平化行为相似但不一样。对于表现出这种行为的事物,是否有一个函数式编程术语?

编辑:到目前为止,一些很好的答案,在猫身上挖掘更多,我发现

Semigroup[Option[String]].combine(None, Some("b"))
res0: Option[String] = Some(b)

Semigroup[Option[String]].combine(Some("a"), Some("b"))
res1: Option[String] = Some(ab)

SemigroupK[Option].combineK(None, Some("b"))
res2: Option[String] = Some(b)

SemigroupK[Option].combineK(Some("a"), Some("b"))
res3: Option[String] = Some(a)

SemigroupK[List].combineK(List("a"), List("b"))
res4: List[String] = List(a, b)

Alternative[List].unite(List(None, Some("a"), Some("b")))
res4: List[String] = List(a, b)

所以我现在看到 scalazAlt和 haskell与 catAlternative不太一样Alternative。更有趣的是SemigroupKPlus根据猫文档在 scalaz 中调用)。
所以我们可以说这种行为是由一个类型表现出来的,如果没有一个半群作为它的内部类型,你就不能定义一个半群(因为我们可能会说 scalazAlt和 haskellAlternative是这种类型的半群)?

4

2 回答 2

2

相当一部分 Scala 的灵感来自于 Haskell 中的类似概念。在这种特殊情况下,orElse非常接近类型类中的“替代”运算<|>Alternative

在 Haskell 中, anApplicative是 a Functor(阅读:它包含事物并具有与这些事物交互的某种方式),它具有一些有意义的“组合”这些事物的幺半群方式:<*>. 我们可以认为<*>它与 Scala 有点相似(尽管不相同)andThen,因为它需要两次“成功”的计算并对它们进行排序。在这个类比下,anAlternative提供Applicative了一种从失败中“恢复”的方法,<|>Scala 的orElse.

既然你提到了 monads,Applicative是 的弱化Monad,从某种意义上说,每一个Monad都是一个,Applicative但不是每一个Applicative都是必然的Monad。例如,多维数组可以很容易地做成Applicative但不能做成Monad

因此,总而言之,我相信您正在寻找的术语是“具有替代功能的应用函子”,由类型类在 Haskell 中编码Alternative。如果你想听起来非常傲慢,我们可以用它在数学上严谨的名字来称呼它:一个强大的松散的幺半群函子,由一个额外的幺半群结构支持。但这只是我们在炫耀。

于 2018-11-04T23:46:37.243 回答
1

Alt

https://github.com/scalaz/scalaz/blob/series/7.3.x/core/src/main/scala/scalaz/Alt.scala

基本上,orElse变成alt

def alt[A](a1: =>F[A], a2: =>F[A]): F[A].

于 2018-11-04T23:45:41.910 回答