【问题标题】:standard specialization of Either where type of Left and Right is the sameEither 的标准特化,其中 Left 和 Right 的类型相同
【发布时间】:2014-08-05 21:14:26
【问题描述】:

在 Haskell 或 Scala 中是否有标准的 Either 特化使 LeftRight 中包含的类型相同?

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

data SpecializedEither a = Left a | Right a

这也可能被认为是对Maybe 的轻微概括,它使Nothing 保持一个值。

edit:Ganesh 提出了一个很好的观点,即不能为这种类型定义 Monad 实例。有没有更好的方法来做我想做的事情?

【问题讨论】:

  • (Bool, a) 如果你眯着眼睛很接近
  • 我考虑过,但后来我不得不特意为它编写 Monad 实例。我希望有一些东西 [standand] 我可以使用。
  • 这个最近的问题说明了为什么你实际上不能为它获取 Monad 实例:stackoverflow.com/questions/24233245/…
  • @GaneshSittampalam 这仅表明Either 的“标准实例”失败了,对吧?还有其他适用于SpecializedEither 的实例。
  • 哦,是的,虽然我不确定任何替代方案是否有意义。

标签: scala haskell types


【解决方案1】:

怎么样:

type Foo[T] = Either[T, T]
val x: Foo[String] = Right("")
// Foo[String] = Right()

【讨论】:

    【解决方案2】:

    只要eMonoid,就有a standard Monad instance on ((,) e)

    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) 是同构的(以两种方式),只要我们为Bool 选择Monoid,我们就会得到一个Monad 实例。有两个(实际上是四个,参见 cmets)Monoids,“and”类型和“or”类型。从本质上讲,这个选择最终决定了您的任一方的LeftRight 是否为“默认”。如果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)
    

    【讨论】:

    • 从技术上讲,Bools 还有另外两种幺半群可能性,由(==)(/=)(又名“xor”)运算符给出,尽管Data.Monoid 中没有预定义这些可能性。
    • 这是一个很好的观点。我从来没有检查过这些是否也符合法律。
    • Bool 上已经有新的类型包装器用于“或”和“和”幺半群,在 Data.Monoid 中定义,命名为 AnyAllMonad ((,) e) 实例是相当于Writer monad。所以我怀疑Writer AnyWriter All 是这里想要的单子。
    • @AndrewC True == b = False /= b = b
    • @illabout Writer w a 等价于 (w, a),与我在这里给出的 monad 实例完全相同。 Any 和 All 是 Bool 的包装器,它赋予它两种(四种)Monoid 语义。因此,Writer AnyWriter All((,) Bool) 的两个版本,具有明确定义的 monad 实例。显然,Writer 是一种流行的结构,因此可以说这种 monad 是“标准的”。
    猜你喜欢
    • 2021-01-18
    • 2021-11-12
    • 1970-01-01
    • 2018-10-09
    • 2018-04-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    相关资源
    最近更新 更多