为什么`Left` 和`Right` 有两个类型参数? [英] Why do `Left` and `Right` have two type parameters?
问题描述
我知道现在很难在不破坏现有代码的情况下进行更改,但我想知道为什么首先要这样做.
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,即对于任何类型A
和 B
你有
Either
is the canonical coproduct, i.e. for any types A
and B
you have
- 类型
任一A,B≈A⊕B
- 两个共投影
LeftA,B : A ->A⊕B
和RightA,B : B ->A⊕B
- 对于任何类型
Y
和任何函数fA : A ->Y
和fB : B ->Y
,只存在一个函数f : A⊕B ->Y
具有fA = f ∘ LeftA,B
和fB = f ∘ RightA,B
.
- The type
EitherA,B ≈ A ⊕ B
- Two coprojections
LeftA,B : A -> A⊕B
andRightA,B : B -> A⊕B
- such that for any type
Y
and any functionsfA : A -> Y
andfB : B -> Y
, there exists exactly one functionf : A⊕B -> Y
with the property thatfA = f ∘ LeftA,B
andfB = 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屋!