什么是 Maybe 类型,它是如何工作的?
What is the Maybe type and how does it work?
我刚开始在 Haskell 中编程,我遇到了以下定义:
calculate :: Float -> Float -> Maybe Float
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
与大多数编程语言中的 "null pointer" 进行比较。默认情况下,你不会为你定义的数据类型实现空指针(如果你这样做,所有这些 "nulls" 看起来都不一样),通过添加 Nothing
你有一个通用的空指针。
因此,使用 Maybe
表示可能无法计算输出是很有用的。您当然也可以在小于 0
:
的值上出错
sqrt x | x >= 0 = Just $ ...
| otherwise = error "The value must be larger or equal to 0"
但是错误通常不会在类型签名中提及,如果您不考虑它们,编译器也没有任何问题。 Haskell 也转向 total 函数:最好总是尝试至少 return 一个值(例如 Nothing
)所有可能的输入。
如果你以后想使用Maybe a
的结果,你需要写:
succMaybe :: Maybe Int -> Maybe Int
succMaybe (Just x) = Just (x+1)
succMaybe _ = Nothing
但是通过为第一种情况编写 Just
,您以某种方式警告自己可能会发生 Nothing
。您还可以通过引入 "default" 值来摆脱 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
,函数将应用于它并 returned,如果输入值是 Nothing
,将使用默认值。
使用 Maybe a
可能会很困难,因为您总是需要考虑 Nothing
的情况,要简化这一点,您可以使用 Maybe monad.
Tom Schrijvers 还表明 Maybe
是类型代数中的后继函数:你向你的类型添加一个额外的值(Either
是一个加法(,)
是乘法的类型代数等价物)。
我刚开始在 Haskell 中编程,我遇到了以下定义:
calculate :: Float -> Float -> Maybe Float
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
与大多数编程语言中的 "null pointer" 进行比较。默认情况下,你不会为你定义的数据类型实现空指针(如果你这样做,所有这些 "nulls" 看起来都不一样),通过添加 Nothing
你有一个通用的空指针。
因此,使用 Maybe
表示可能无法计算输出是很有用的。您当然也可以在小于 0
:
sqrt x | x >= 0 = Just $ ...
| otherwise = error "The value must be larger or equal to 0"
但是错误通常不会在类型签名中提及,如果您不考虑它们,编译器也没有任何问题。 Haskell 也转向 total 函数:最好总是尝试至少 return 一个值(例如 Nothing
)所有可能的输入。
如果你以后想使用Maybe a
的结果,你需要写:
succMaybe :: Maybe Int -> Maybe Int
succMaybe (Just x) = Just (x+1)
succMaybe _ = Nothing
但是通过为第一种情况编写 Just
,您以某种方式警告自己可能会发生 Nothing
。您还可以通过引入 "default" 值来摆脱 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
,函数将应用于它并 returned,如果输入值是 Nothing
,将使用默认值。
使用 Maybe a
可能会很困难,因为您总是需要考虑 Nothing
的情况,要简化这一点,您可以使用 Maybe monad.
Tom Schrijvers 还表明 Maybe
是类型代数中的后继函数:你向你的类型添加一个额外的值(Either
是一个加法(,)
是乘法的类型代数等价物)。