Haskell 或 Scala 中是否有 Either
的标准特化,使 Left
和 Right
中包含的类型成为相同类型?
在 Haskell 中,我想要这样的东西:
data SpecializedEither a = Left a | Right a
这也可能被认为是
Maybe
的轻微泛化,它使 Nothing
保持一个值。编辑:Ganesh 提出了一个很好的观点,即无法为这种类型定义 Monad 实例。有没有更好的方法来做我想做的事情?
最佳答案
只要 Monad
是 ((,) e)
就有 a standard e
instance on Monoid
instance Monoid e => Monad ((,) e) where
return a = (mempty, a)
(e1, a) >>= f = let (e2, b) = f a in (e1 <> e2, b)
由于
Either a a
和 (Bool, a)
是同构的(以两种方式),我们只要为 Monad
选择一个 Monoid
就会得到一个 Bool
实例。有两个(实际上是四个,见评论)这样的 Monoid
s,“and”类型和“or”类型。本质上,这个选择最终决定了你的 Left
还是 Right
一侧是“默认”。如果 Right
是默认的(因此 Left
覆盖了它),那么我们得到data Either1 a = Left1 a | Right1 a
get1 :: Either1 a -> a
get1 (Left1 a) = a
get1 (Right1 a) = a
instance Monad Either1 where
return = Right1
x >>= f = case (x, f (get1 x)) of
(Right1 _, Right1 b) -> Right1 b
(Right1 _, Left1 b) -> Left1 b
(Left1 _, y ) -> Left1 (get1 y)
关于scala - 左和右类型相同的任何一种的标准特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24237031/