使用scala作为参考,我们在orElse
,PartialFunction
和猫Option
等几个地方看到了回退行为(EitherOps
)。
这与单子的扁平化行为相似但不相同。表现出这种行为的事物是否有功能性的编程术语?
编辑: 到目前为止,我发现了一些很好的答案,发现它们更多地藏在猫中
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)
所以我现在看到斯卡拉斯Alt
和哈斯克尔Alternative
与猫Alternative
不太一样。更有趣的是SemigroupK
(根据cats文档在scalaz中称为Plus
)。
因此,我们可以说这种行为是由一种类型表现出来的吗?对于该类型,您不能定义一个半群而没有内部类型也具有半群(因为我们可能会说scalaz Alt
和haskell Alternative
是这样的)?
答案 0 :(得分:2)
大量的Scala受到Haskell中类似概念的启发。在这种特殊情况下,orElse
非常接近Alternative
类型类中的“替代”运算符<|>
。
在Haskell中,Applicative
是Functor
(读:它包含事物并具有与这些事物交互的某种方式),它具有一些有意义的“组合”这些事物的单调方式:{{ 1}}。我们可以认为<*>
与Scala的<*>
有点相似(尽管不完全相同),因为它需要两次“成功”计算并对它们进行排序。在这种情况下,andThen
是Alternative
,它提供了一种从故障中“恢复”的方法,因此Applicative
或多或少是Scala的<|>
。
自从您提到单子之后,orElse
是Applicative
的弱点,因为每个Monad
都是Monad
,但不一定每个Applicative
Applicative
。例如,多维数组可以easily制成Monad
,而不能制成Applicative
。
因此,总而言之,我相信您要查找的术语是“具有替代功能的应用函子”,在Haskell中用Monad
类型类进行了编码。如果您想听起来非常自大,我们可以用数学上严格的名称来称呼它:强大的松散单曲面函子,并带有一个附加的单曲面结构。但这只是我们在炫耀。
答案 1 :(得分: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]
。