所以有趣的Either是你可以将它用作类型级cons操作符.
A `Either` (B `Either` (C `Either` (D `Either` Void))) --> [A,B,C,D]
Run Code Online (Sandbox Code Playgroud)
所以我们所需要做的就是明确这一点.你需要ghc-7.8来支持封闭的数据系列:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
-- ...
type family OneOf (as :: [*]) :: * where
OneOf '[a] = a
OneOf (a ': as) = Either a (OneOf as)
Run Code Online (Sandbox Code Playgroud)
现在,您可以更简洁地编写类型:
aorborc :: Parser (OneOf '[A, B, C])
aorborc = a | (b | c)
Run Code Online (Sandbox Code Playgroud)
它仍然Either在引擎盖下,因此您仍然可以轻松地与所有使用的现有代码进行互操作Either,这很好.