解释一段Haskell代码

时间:2014-03-17 13:23:50

标签: haskell

有人知道这段代码是做什么的吗?我知道它验证了给定年份,但我并没有真正理解整个过程。

tempYear <- getLine
case reads tempYear :: [(Integer, String)] of
     [(n, "")] -> do let year = read tempYear :: Int

2 个答案:

答案 0 :(得分:3)

我想case reads可以处理getLine没有返回正确数字的情况。 reads返回可能答案的列表。如果tempYear以非数字开头,则返回空列表。如果字符串中还有其他字母或类似内容,则该字母前的数字为n。但是元组中的第二个值不是空字符串,而是字符串中未解析的其余部分。

但是,我不知道为什么他会首先阅读Integer然后再阅读Int。如果两种类型相同,n也将等于year

答案 1 :(得分:2)

如果你传递一个无法解析为整数的字符串,

read会抛出一个无法捕获的异常,所以如果你想接受可能无法解析的字符串,你需要使用相关的reads函数代替。 reads有一个棘手的接口:它不返回单个整数结果,而是返回一个可能的解析结果列表,每个解析结果都是解析的原始字符串的未解析的剩余部分。

  • 如果解析失败,它将返回空列表
  • 如果你通过它&#34; 10asd&#34;它将返回一个单元素列表,其中10作为解析后的数字和#34; asd&#34;作为剩余的
  • afaik,在解析整数时,reads永远不会返回包含多个结果的列表。

在您的情况下,他正在使用模式匹配来检查来自读取的返回值是否恰好是单个元素的列表,并且这个单独的解析结果留下了一个空的余数(意味着解析成功并且只得到一个数字))。

但是,有点奇怪的是他会把这个数字重新作为一个Int。通常你只需从读取结果中取出数字。 (如果你真的需要一个Int,只需告诉读取首先读取Int而不是Integer)

case reads tempYear :: [(Integer, String)] of
 [(n, "")] -> n

此外,使用读取的全部意义是避免未处理的异常,但如果我们不覆盖该模式匹配中的所有情况,我们仍会得到未处理的异常!如果解析失败,您仍需要告诉您该怎么做:

case reads tempYear :: [(Integer, String)] of
 [(n, "")] -> n
 _         -> 0  --return a default value?

如果没有合理的默认值并且您只想&#34;返回null&#34;,那么Haskel的方法是返回Maybe Integer而不是Integer:< / p>

case reads tempYear :: [(Integer, String)] of
 [(n, "")] -> Just n
 _         -> Nothing