所以说我们有一个函数sqrt的例子,它给我们一个浮点数的平方根,但不会在负输入上中止。那么sqrt的类型是什么。
我被告知答案是:
sqrt :: Maybe Float -> Float
然而我不明白Maybe会做什么,它只是意味着我们可以提供任何输入或者它意味着什么。
答案 0 :(得分:6)
Maybe
是一个具有简单定义的类型构造函数:
data Maybe a
= Just a
| Nothing
此语法读作“创建一个名为Maybe
的新类型构造函数,它接受一个类型参数。它有两个值构造函数:Just
,它采用类型为a
的单个参数,或者Nothing
“。
当我们编写接受Maybe
参数的函数时,我们可以对其进行模式匹配以处理这两种情况。
foo :: Maybe String -> String
foo (Just str) = str
foo Nothing = "There was nothing!"
如果函数没有对所有输入有意义的定义,那么我们可以使用Maybe
来表示。例如,Prelude中的sqrt
会返回NaN
的负值。我们可以编写一个返回Maybe
的不同版本:
import qualified Prelude
import Prelude hiding (sqrt)
sqrt :: Float -> Maybe Float
sqrt x
| x < 0 = Nothing
| otherwise = Just (Prelude.sqrt x)
我们可能会将这种类型读作“如果你给我一个浮点数,那么我可以返回浮点数。”
答案 1 :(得分:0)
我已经撤回了我的近距离投票,虽然对另一个问题的最佳答案或多或少地回答了这个问题,但这本身并不是一个骗局。
首先,让我们谈谈参数化类型。
如果我说(语言不可知)
Array<String>
我们有一个字符串数组。字符串数组["foo", "bar"]
的类型为 Array<String>
。 'Array'本身并不是一个完整的类型*,我们有一个 的数组。换句话说,我们会使用类型Array
参数化String
。
Maybe
也是这样的,你有一个(在这种情况下)一个Maybe Float
,可以是Just Float
或Nothing
。现在,就像编译器不会让你将int列表传递给一个带有int的函数一样,它不允许你将Maybe T
传递给一个类型为T
的函数。您必须处理Nothing
案例,类型系统会阻止忽略处理失败案例。所以你的sqrt函数应该有签名
sqrt :: Float -> Maybe Float
要反映这样一个事实:尽管你可以传入任何浮点数,但如果参数为负数,结果可能不存在。
*为了讨论的目的。