为什么`Left` 和`Right` 有两个类型参数? [英] Why do `Left` and `Right` have two type parameters?

查看:45
本文介绍了为什么`Left` 和`Right` 有两个类型参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道现在很难在不破坏现有代码的情况下进行更改,但我想知道为什么首先要这样做.

I understand it would be difficult to change now without breaking existing code, but I'm wondering why it was done that way in the first place.

为什么不只是:

sealed trait Either[+A, +B]
case class Left[A](x: A) extends Either[A, Nothing]
case class Right[B](x: B) extends Either[Nothing, B]

这里有什么我看不到的缺点吗...?

Is there some drawback here that I'm failing to see...?

推荐答案

不确定这个答案与 Scala 的相关性如何,但肯定是在 Haskell 中,显然 Scala 的 Either 是从那里借来的所以这可能是 Scala 这样做的最好的历史原因.

Not sure how relevant this answer really is to Scala, but it certainly is in Haskell which is evidently where Scala's Either was borrowed from and so that's probably the best historical reason for why Scala did it this way.

Either 是规范的coproduct,即对于任何类型AB 你有

Either is the canonical coproduct, i.e. for any types A and B you have

  • 类型任一A,B≈A⊕B
  • 两个共投影LeftA,B : A ->A⊕BRightA,B : B ->A⊕B
  • 对于任何类型 Y 和任何函数 fA : A ->YfB : B ->Y,只存在一个函数 f : A⊕B ->Y 具有 fA = f ∘ LeftA,BfB = f ∘ RightA,B.
  • The type EitherA,B ≈ A ⊕ B
  • Two coprojections LeftA,B : A -> A⊕B and RightA,B : B -> A⊕B
  • such that for any type Y and any functions fA : A -> Y and fB : B -> Y, there exists exactly one function f : A⊕B -> Y with the property that fA = f ∘ LeftA,B and fB = f ∘ RightA,B.

为了在数学上表述这一点,明确您正在使用的特定 Left 的信息是非常有帮助的,因为否则态射的域将全都不清楚.在 Scala 中,这可能是不必要的,因为隐式协变转换,但在数学和 Haskell 中不是.

To formulate this mathematically, it is quite helpful to have the information which particular Left you're working with explicit, because else the domains of the morphisms would be all unclear. In Scala this may be unnecessary because of implicit covariant conversion, but not in maths and not in Haskell.

在 Haskell 中,这根本不是问题,因为类型推断会自动执行所需的操作:

In Haskell it isn't really an issue at all, because type inference will automatically do what's needed:

GHCi, version 8.6.5: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /tmp/haskell-stack-ghci/2a3bbd58/ghci-script
Prelude> let right2 = Right 2
Prelude> let left42 = Left 42.0
Prelude> (+) <$> right2 <*> left42
Left 42.0

显然,在 Scala 中,Haskell 只是将 left42 未指定的第二个参数作为 类型变量(除非启用了单态限制),因此您可以稍后在任何需要一些 Either Double R 的任何类型 R 的上下文中使用它.当然也可以明确表示

Unlike, apparently, in Scala, Haskell just leaves the unspecified second argument of left42 as a type variable (unless the monomorphism restriction is enabled), so you can later use it in any context requiring some Either Double R for any type R. Of course it's possible to make that explicit too

right2 :: Either a Int
right2 = Right 2

left42 :: Either Double a
left42 = Left 42

main :: IO ()
main = print $ (+) <$> right2 <*> left42

这当然也可以在 Scala 中实现.

which surely is possible in Scala just as well.

这篇关于为什么`Left` 和`Right` 有两个类型参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆