左侧和右侧类型相同的标准专业化

ill*_*out 4 haskell types scala

是否有一个标准的专业化Either在Haskell或Scala中,使所含的类型LeftRight同类型的?

在Haskell中,我想要这样的东西:

data SpecializedEither a = Left a | Right a
Run Code Online (Sandbox Code Playgroud)

这也可以被认为是一种轻微的概括Maybe,使得Nothing保持一个价值.

编辑:Ganesh提出了一个非常好的观点,即无法为此类型定义Monad实例.有没有更好的方法来做我想做的事情?

J. *_*son 11

只要是a,就有一个标准Monad实例((,) e)eMonoid

instance Monoid e => Monad ((,) e) where
  return a = (mempty, a)
  (e1, a) >>= f = let (e2, b) = f a in (e1 <> e2, b)
Run Code Online (Sandbox Code Playgroud)

由于Either a a(Bool, a)是同构的(有两种方式),我们得到了一个Monad尽快实例作为我们挑选MonoidBool.有两个(真四,看评论)这样的Monoid年代,"和"型和"或"类型.从本质上讲,这种选择最终决定是否对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)
Run Code Online (Sandbox Code Playgroud)

  • 从技术上来说,`Bool'还有两个monoid可能性,由`(==)`和`(= =)`(又名"xor")运算符给出,尽管那些在`Data.Monoid`中没有预定义. (3认同)
  • 在`Bool`中有"or"和"and"monoids的新类型包装器,在`Data.Monoid`中定义,名为`Any`和`All`,而`Monad((,)e)`实例是相当于`Writer` monad.所以我怀疑`Writer Any`或`Writer All`是这里所需的monad. (2认同)