你希望一个Alternative实例给你什么。我认为让您了解如何Alternative和Semigroup不同的一个好方法是查看另一种具有两者实例的类型:例如Maybe String:
λ > Just "a" <> Just "b"
Just "ab"
λ > Just "a" <> Nothing
Just "a"
λ > Nothing <> Just "b"
Just "b"
λ > Nothing <> Nothing
Nothing
λ > Just "a" <|> Just "b"
Just "a"
λ > Just "a" <|> Nothing
Just "a"
λ > Nothing <|> Just "b"
Just "b"
λ > Nothing <|> Nothing
Nothing
好的,所以主要区别似乎是Just "a"和Just "b"。这是有道理的,因为您在 的情况下将它们组合在一起,Semigroup而不是在 . 的情况下采用左偏选项Alternative。
现在为什么你不能有Alternative一个Either. 如果您查看属于Alternative类型类的函数:
λ > :i Alternative
class Applicative f => Alternative (f :: * -> *) where
empty :: f a
(<|>) :: f a -> f a -> f a
some :: f a -> f [a]
many :: f a -> f [a]
{-# MINIMAL empty, (<|>) #-}
看起来它定义了一个empty; 这是(<|>)操作者的身份。案例中的同一性意味着同一性与其他事物之间的选择始终是其他事物。
现在,您将如何为 构建身份Either e a?如果您查看Alternative实例上的约束,您会发现它需要f有一个Applicative实例。没关系,Either有一个Applicative为Either e. 如您所见,Either它只是第二个类型变量(a在 的情况下Either e a)的应用函子。所以一个身份 forEither e也需要e有一个身份。虽然可以构造一个类型,其中e有一个实例,Alternative你不能为它创建一个实例Alternative,Either因为e类型类定义中没有这样的约束(类似于:)(Alternative e, Applicative (f e)) => Alternative (f e)。
TL;DR : 很抱歉,如果我在漫无边际f的情况下失去了你,唯一的缺点是如果Either是错误的类型,Alternative需要f :: * -> *whileEither是类型的 Either :: * -> * -> *
所以Maybe可以有一个 的实例,Alternative因为它有种类 Maybe : * -> *并且Nothing有empty. 查看所有实例Alternative并注意每个实例数据类型的种类。
你可以在 ghci 中找到一种数据类型:k:
λ > :k Maybe
Maybe :: * -> *
λ > :k Either
Either :: * -> * -> *