Haskell代码tail空列表报错处理:如何给exponent设默认值1?
解决Haskell中tail空列表报错的问题
你的代码中exponent的定义在目标字符串不含^时,dropWhile (/= '^')会返回空列表,调用tail就会触发运行时错误。要实现“出错时赋值1”的逻辑,我们可以通过模式匹配或安全读取函数来处理异常场景:
修改后的完整健壮版代码
import Text.Read (readMaybe) -- 导入安全读取模块 internalRepresentation :: [String] -> [(Int, Char, Int)] internalRepresentation xs | null xs = [] | all isDigit (head xs) = (read (head xs), ' ', 0) : internalRepresentation (tail xs) | head (head xs) == '-' = (-read (takeWhile isDigit pos_mon) :: Int, head (dropWhile isDigit pos_mon), exponent) : internalRepresentation (drop 1 xs) | otherwise = (read (takeWhile isDigit (head xs)) :: Int, head (dropWhile isDigit (head xs)), exponent) : internalRepresentation (drop 1 xs) where pos_mon = tail (head xs) exponent = case dropWhile (/= '^') (head xs) of [] -> 1 -- 字符串中没有^,直接赋值1 '^':rest -> case readMaybe rest :: Maybe Int of Just n -> n -- ^后是合法数字,正常读取 Nothing -> 1 -- ^后不是合法数字,赋值1 _ -> 1 -- 理论不会触发,仅作兜底
关键修改说明
- 使用
readMaybe替代read:这个函数读取失败时返回Nothing而非抛出错误,避免了^后无合法数字的报错场景。 - 分情况处理
^的存在性:- 若
dropWhile (/= '^')返回空列表,说明字符串里没有^,直接赋值1。 - 若找到
^,则尝试读取其后的内容,读取失败时同样赋值1。
- 若
简化版(仅处理无^的场景)
如果只需要解决“无^时tail空列表报错”的问题,不需要处理^后无数字的情况,可以用更简洁的写法(无需额外导入):
internalRepresentation :: [String] -> [(Int, Char, Int)] internalRepresentation xs | null xs = [] | all isDigit (head xs) = (read (head xs), ' ', 0) : internalRepresentation (tail xs) | head (head xs) == '-' = (-read (takeWhile isDigit pos_mon) :: Int, head (dropWhile isDigit pos_mon), exponent) : internalRepresentation (drop 1 xs) | otherwise = (read (takeWhile isDigit (head xs)) :: Int, head (dropWhile isDigit (head xs)), exponent) : internalRepresentation (drop 1 xs) where pos_mon = tail (head xs) exponent = let afterCaret = dropWhile (/= '^') (head xs) in if null afterCaret then 1 else read (tail afterCaret) :: Int
内容的提问来源于stack exchange,提问作者Guilherme Moreira
相关产品推荐
相关产品推荐

