Haskell:将 Maybe 和 Either 类型组合为单一类型

0 haskell types

我必须将Maybeand与 、 的三个构造函数组合Either起来,并调用, and 。MayEitherLeftRightNothingMyLeftMyRightMyNothing

\n

这就是我所做的:

\n
data MayEither = Maybe  { myNothing :: Nothing }\n               | Either { myLeft :: Left }\n               | Either { myRight :: Right } deriving Show\n
Run Code Online (Sandbox Code Playgroud)\n

但这给了我一个Multiple declarations of \xe2\x80\x98Either\xe2\x80\x99错误。\n我如何正确组合这些类型?

\n

Dan*_*ner 7

需要发生两件事:

  1. 您需要为每个数据构造函数指定不同的名称。
  2. 您需要给出记录中字段的类型。

请注意Nothing, 、Left、 和Right是和类型的数据构造函数——它们本身不是类型!因此,声称字段具有类型并不完全正确。同样,和是类型构造函数,因此以它们命名数据构造函数充其量只是一种误导,在这种情况下几乎肯定是错误的。MaybeEitherNothingMaybeEither

那么让我们再试一次。首先,我们将选择新的数据构造函数名称。

data MayEither = MyNothing { myNothing :: <TODO> }
               | MyLeft { myLeft :: <TODO> }
               | MyRight { myRight :: <TODO> }
Run Code Online (Sandbox Code Playgroud)

现在,应该有什么类型myNothingNothing嗯, /的全部意义MyNothing在于,那里什么都没有。所以我们根本不应该有那个字段!

data MayEither = MyNothing
               | MyLeft { myLeft :: <TODO> }
               | MyRight { myRight :: <TODO> }
Run Code Online (Sandbox Code Playgroud)

该字段应该具有什么类型myLeft?嗯,大概我们希望里面能有任何东西。实现这一点的方法是参数化我们的类型——就像Maybe采用一个类型级参数和Either采用两个类型级参数一样。我们将做同样的Either事情,并接受两个参数,以便我们的myLeftmyRight字段可以是任意的并且不需要匹配。

data MayEither a b = MyNothing
                   | MyLeft { myLeft :: a }
                   | MyRight { myRight :: b }
Run Code Online (Sandbox Code Playgroud)

现在这是有效的 Haskell。但是将记录语法和总和类型结合起来几乎总是一个坏主意。我想如果我自己这样做的话,我会完全放弃字段名称。

data MayEither a b = MyNothing
                   | MyLeft a
                   | MyRight b
-- OR
data MayEither a b = MyNothing | MyLeft a | MyRight b
Run Code Online (Sandbox Code Playgroud)