Maybe a是一个普通的数据类型,定义为:
data Maybe a = Just a | Nothing
因此有两种可能性:或者您将a 类型的值定义为Just a(如Just 3),或者Nothing 以防查询没有答案。
它旨在定义为一种为非全函数定义输出的方法。
例如:假设您要定义sqrt。平方根只针对正整数定义,因此您可以将sqrt 定义为:
sqrt x | x >= 0 = Just $ ...
| otherwise = Nothing
使用... 计算x 的平方根的方法。
有些人将Nothing 与大多数编程语言中的“空指针”进行比较。默认情况下,您不会为您定义的数据类型实现空指针(如果您这样做,所有这些“空”看起来都不同),通过添加Nothing,您就有了一个通用的空指针。
因此,使用Maybe 表示可能无法计算输出是很有用的。您当然也可以在小于0 的值上出错:
sqrt x | x >= 0 = Just $ ...
| otherwise = error "The value must be larger or equal to 0"
但是错误通常不会在类型签名中提及,如果您不考虑它们,编译器也不会有任何问题。 Haskell 也在转向 total 函数:最好总是尝试至少为所有可能的输入返回一个值(例如 Nothing)。
如果您以后想使用Maybe a 的结果,例如,您需要编写:
succMaybe :: Maybe Int -> Maybe Int
succMaybe (Just x) = Just (x+1)
succMaybe _ = Nothing
但是通过为第一种情况写Just,您以某种方式警告自己有可能发生Nothing。您还可以通过引入“默认”值来摆脱 Maybe:
justOrDefault :: a -> Maybe a -> a
justOrDefault _ (Just x) = x
justOrDefault d _ = d
内置的maybe函数(注意小写),结合了前面的两个函数:
maybe :: b -> (a -> b) -> Maybe a -> b
maybe _ f (Just x) = f x
maybe z _ Nothing = z
所以你指定一个b(默认值)和一个函数(a -> b)。如果Maybe a为Just x,则对其应用函数并返回,如果输入值为Nothing,则使用默认值。
使用Maybe a 可能很困难,因为您始终需要考虑Nothing 的情况,为了简化这一点,您可以使用Maybe monad。
Tom Schrijvers 还表明 Maybe 是类型代数中的后继函数:您为您的类型添加一个额外的值(Either 是一个加法,(,) 是类型代数相当于乘法)。