大家晚上好,我是哈斯凯尔的新手.我试图总结一个读取字符串Unicode值的列表,并将它们存储在一个列表中,然后将整数加起来.
getLetterUnicodeValue :: Char -> Int
getLetterUnicodeValue l = (ord l) - 64
unicodeValueList :: String -> [Int]
unicodeValueList x = getLetterUnicodeValue (head x) : unicodeValueList (tail x)
total :: [Int] -> Int
total [] = 0
total x = (head x) + (total (tail x))
Run Code Online (Sandbox Code Playgroud)
当字符串到达最后一个字符并且总结功能无法成功执行时,我得到了空列表的错误.有什么办法可以在功能unicodeValueList结束时停止它.
*** Exception: Prelude.head: empty list
Run Code Online (Sandbox Code Playgroud)
避免此异常的最可靠方法是不使用head.相反,您可以使用模式匹配来获取列表的头部和尾部:
unicodeValueList (x:xs) = getLetterUnicodeValue x : unicodeValueList xs
total (x:xs) = x + total xs
Run Code Online (Sandbox Code Playgroud)
这种方式x与xs将只可当列表不为空,并可以保证你永远不小心访问一个空列表的头部或尾部.
当然,现在您将收到模式匹配不完整的警告:您没有指定列表为空时应该发生什么.当然,之前也是如此,但是现在您使用模式匹配,编译器实际上可以看到它并警告您(而前一代码在运行时崩溃而没有任何预先警告).
那么当列表为空时应该怎么做?好吧,空字符串不包含unicode值,对吧?所以它应该在输入为空时返回空列表:
unicodeValueList [] = []
Run Code Online (Sandbox Code Playgroud)
当然,您不需要模式匹配来修复错误.你可以使用一个if来确保你只调用head,tail当列表不为空时.但是,如果您这样做,编译器将无法验证您的检查是否有序.如果您使用模式匹配并完全避免不安全head和tail函数,您将永远无法意外访问空列表的头部或尾部,如果您忘记考虑列表可能为空,编译器将发出警告.