我想知道为什么read "1" :: Maybe Int
会在运行时键入检查并抛出异常。
read
有可能返回Maybe a
吗?这是Text.Read.readMaybe
应该做的。
Prelude> read "1" :: Maybe Int
*** Exception: Prelude.read: no parse
我想知道为什么
read "1" :: Maybe Int
会键入检查
因为"1"
具有String
类型,因此可以接受作为read
的参数,并且Maybe Int
实现Read
,因此可以作为返回类型的Read
。
并在运行时引发异常。
因为"1"不是Maybe Int
的有效字符串表示形式。
读取是否有可能返回
Maybe a
?
是的,例如read "Just 42" :: Maybe Int
是Just 42
,read "Nothing" :: Maybe Int
是Nothing
.
基本上,您可能从show x
中获取的任何字符串,其中x :: Maybe Int
也可以作为参数提供给read
以获取Maybe Int
。
或者更一般地说,任何show x
的输出,其中x :: T
和T
是Show
和Read
的实例,都可以提供给read
以获得类型T
的值 - 尽管当然实例可以任意定义,因此并非每个实现Read
和Show
的类型都必须遵守该"契约"。
简而言之:您解析Maybe a
类型的文本表示形式,而不是a
为非总函数,其中Nothing
用于指定解析失败。
好吧,read
通常与show
相反。因此,它将解析对象的表示形式,这通常是您将对象作为级联数据构造函数写入对象的方式。
现在Maybe a
是Show
族的一种类型,因为它包装的元素也是Show
的实例,如下所示:
instance Show a => Show (Maybe a) where
show Nothing = "Nothing"
show (Just x) = "Just "++ show x
(实际上它有点复杂,因为它还会引入括号,例如,如果您将Just 1
包装在Just
中(。
所以反过来也可以解析。例如:
Prelude> read "Nothing" :: Maybe Int
Nothing
Prelude> read "Just5" :: Maybe Int
Just 5
因此,Maybe a
作为一种read
类型不是用于">非总计"函数,而是用于解析Maybe a
类型的文本表示。
因此,它解析带有前缀"Nothing"
和"Just"
的字符串(也可以解析一些带括号的此类"表达式"(。