haskell 中的函数异常中的非详尽模式
Non-exhaustive patterns in function Exception in haskell
我有这个代码:
import Data.Char
foo :: String -> String
foo (x:xs) = if (digitToInt(x)) == 0
then foo xs
else if (digitToInt(x)) /= 0
then replicate (digitToInt(x)) (head $ take 1 xs) ++ foo (tail xs )
else ""
输入:foo "4a5b"
输出:"aaaabbbbb"
此行 if (digitToInt(x)) == 0
检查数字是否为 0,如果是,则它将与字符串的其余部分一起扩展:
示例:
输入:foo "00004a5b"
输出:"aaaabbbbb"
我添加了 else if (digitToInt(x)) /= 0
来检查其他情况。
然而它给了我:
*Main> foo "4a5b"
"aaaabbbbb*** Exception: test.hs:(89,1)-(93,28): Non-exhaustive patterns in function foo
错误。我错过了哪些案例?
函数 foo 中的非详尽模式
此错误发生在运行时,因为尚未根据评估中给出的模式声明函数。这种特殊情况不考虑列表尾部的结尾。
我在下面提出的解决方案是为了概括所提出的用例。
注意函数的定义reproduce
。
reproduce [] .. --Empty list
reproduce (x:[]) .. --A single value in the list
reproduce (x:y:[]) .. --A list with only two elements x and y
reproduce (x:y:xs) .. --A list with the first two elements x and y and the rest of the list xs
Here is a solution to the problem presented considering a
generalization of the foo function.
代码:
--We import the functions to use
import Data.List (replicate, group, groupBy, all)
import Data.Char (isDigit)
--Grouping by digits
gbDigit :: String -> [String]
gbDigit = groupBy (\x y -> (isDigit x) && (isDigit y)) --ETA reduce form
--Grouping by nor digits
gbNoDigit :: String -> [String]
gbNoDigit s = fmap concat $ groupBy (\x y -> not (all isDigit x) && not (all isDigit y)) (gbDigit s)
--Prepare applying grouping
--by digit first and not by digit afterwards, therefore:
prepare = gbNoDigit
foo :: String -> String
foo x = concat $ reproduce (prepare x)
reproduce :: [String] -> [String]
reproduce [] = [] --Empty list, nothing to do
reproduce (x:[]) = [] --A numerical value and nothing to replicate, nothing to do
reproduce (x:y:[]) = (replicate (read x::Int)) y --A numeric value and a string to replicate, so we replicate
reproduce (x:y:xs) = (replicate (read x::Int)) y <> reproduce xs --A numeric value, a string to replicate, and a tail to continue
循序渐进:
- 给定条目 "003aA3b4vX10z"
- 按数字分组:
["003","a","A","3","b","4","v","X","10","z"]
- 按 NoDigits 分组:
["003","aA","3","b","4","vX","10","z"]
- 重现和连接:
"aAaAaAbbbvXvXvXvXzzzzzzzzzz"
测试用例:
Prelude> foo "00004a5b"
Prelude> "aaaabbbbb"
Prelude> foo "4a"
Prelude> "aaaa"
Prelude> foo "4a10B"
Prelude> "aaaaBBBBBBBBBB"
Prelude> foo "3w1.1w6o1l4y1.1com"
Prelude> "www.woooooolyyyy.com"
我有这个代码:
import Data.Char
foo :: String -> String
foo (x:xs) = if (digitToInt(x)) == 0
then foo xs
else if (digitToInt(x)) /= 0
then replicate (digitToInt(x)) (head $ take 1 xs) ++ foo (tail xs )
else ""
输入:foo "4a5b"
输出:"aaaabbbbb"
此行 if (digitToInt(x)) == 0
检查数字是否为 0,如果是,则它将与字符串的其余部分一起扩展:
示例:
输入:foo "00004a5b"
输出:"aaaabbbbb"
我添加了 else if (digitToInt(x)) /= 0
来检查其他情况。
然而它给了我:
*Main> foo "4a5b"
"aaaabbbbb*** Exception: test.hs:(89,1)-(93,28): Non-exhaustive patterns in function foo
错误。我错过了哪些案例?
函数 foo 中的非详尽模式
此错误发生在运行时,因为尚未根据评估中给出的模式声明函数。这种特殊情况不考虑列表尾部的结尾。
我在下面提出的解决方案是为了概括所提出的用例。
注意函数的定义reproduce
。
reproduce [] .. --Empty list
reproduce (x:[]) .. --A single value in the list
reproduce (x:y:[]) .. --A list with only two elements x and y
reproduce (x:y:xs) .. --A list with the first two elements x and y and the rest of the list xs
Here is a solution to the problem presented considering a generalization of the foo function.
代码:
--We import the functions to use
import Data.List (replicate, group, groupBy, all)
import Data.Char (isDigit)
--Grouping by digits
gbDigit :: String -> [String]
gbDigit = groupBy (\x y -> (isDigit x) && (isDigit y)) --ETA reduce form
--Grouping by nor digits
gbNoDigit :: String -> [String]
gbNoDigit s = fmap concat $ groupBy (\x y -> not (all isDigit x) && not (all isDigit y)) (gbDigit s)
--Prepare applying grouping
--by digit first and not by digit afterwards, therefore:
prepare = gbNoDigit
foo :: String -> String
foo x = concat $ reproduce (prepare x)
reproduce :: [String] -> [String]
reproduce [] = [] --Empty list, nothing to do
reproduce (x:[]) = [] --A numerical value and nothing to replicate, nothing to do
reproduce (x:y:[]) = (replicate (read x::Int)) y --A numeric value and a string to replicate, so we replicate
reproduce (x:y:xs) = (replicate (read x::Int)) y <> reproduce xs --A numeric value, a string to replicate, and a tail to continue
循序渐进:
- 给定条目 "003aA3b4vX10z"
- 按数字分组:
["003","a","A","3","b","4","v","X","10","z"]
- 按 NoDigits 分组:
["003","aA","3","b","4","vX","10","z"]
- 重现和连接:
"aAaAaAbbbvXvXvXvXzzzzzzzzzz"
测试用例:
Prelude> foo "00004a5b"
Prelude> "aaaabbbbb"
Prelude> foo "4a"
Prelude> "aaaa"
Prelude> foo "4a10B"
Prelude> "aaaaBBBBBBBBBB"
Prelude> foo "3w1.1w6o1l4y1.1com"
Prelude> "www.woooooolyyyy.com"