Haskell三道编程练习题代码错误排查修复求助
Haskell 练习题代码修复
问题1:sumDaytime 运行报错、daytimeAvg 计算结果错误
问题原因
sumDaytime中直接将Temperature类型的值与Double做加法,类型不匹配:x是被Daytime/Night构造器包装的温度值,需要先解包取出内部的Double数值再参与求和。daytimeAvg中误用整数除法函数div,浮点数除法需要使用/。
修复后完整代码
data Temperature = Night Double | Daytime Double deriving (Eq,Show) isDaytime :: Temperature -> Bool isDaytime (Daytime _) = True isDaytime (Night _) = False countDaytime :: [Temperature] -> Double countDaytime [] = 0.0 countDaytime (x:xs) | isDaytime x = 1.0 + countDaytime xs | otherwise = countDaytime xs sumDaytime :: [Temperature] -> Double sumDaytime [] = 0.0 sumDaytime (x:xs) | isDaytime x = case x of Daytime temp -> temp + sumDaytime xs Night _ -> sumDaytime xs | otherwise = sumDaytime xs daytimeAvg :: [Temperature] -> Double daytimeAvg [] = 0.0 daytimeAvg x = sumDaytime x / countDaytime x
用例验证
daytimeAvg [Night (-5), Night (-6), Daytime 0, Daytime 3, Daytime 5, Daytime 1, Night (-7)]返回2.25,符合预期daytimeAvg [Night 5, Night 0, Daytime 1, Daytime 10, Daytime 8, Daytime 5, Night 2]返回6.0,符合预期
问题2:snakeToCamel 无法转换全字符串、单字符输入报错
问题原因
- 模式匹配不全:只匹配了空串、长度≥2的字符串,遗漏了长度为1的单字符输入分支,运行时会触发非穷尽匹配错误。
- 递归逻辑错误:非下划线分支直接将当前两个字符全部拼入结果,下一轮递归跳过了第二个字符的检查,导致下划线出现在奇数位时无法被识别转换。
- 缺少依赖导入:
toUpper函数需要从Data.Char模块导入。
修复后完整代码
import Data.Char (toUpper) snakeToCamel :: String -> String snakeToCamel "" = "" -- 单字符分支直接返回 snakeToCamel [x] = [x] snakeToCamel (x:xs) | x == '_' = case xs of -- 下划线是最后一个字符直接保留 [] -> [x] -- 遇到下划线,将下一个字符转大写,后续从下一个字符的剩余部分继续递归 (next:rest) -> toUpper next : snakeToCamel rest -- 非下划线字符直接保留,递归处理剩余字符串 | otherwise = x : snakeToCamel xs
用例验证
snakeToCamel "apple"返回"apple",符合预期snakeToCamel "snake_to_camel"返回"snakeToCamel",符合预期snakeToCamel "snake_2_camel"返回"snake2Camel",符合预期snakeToCamel "i_am_in_snake_case"返回"iAmInSnakeCase",符合预期
问题3:match 函数运行不符合预期、存在非穷尽匹配
问题原因
- 模式匹配不全:只匹配了两个参数都是非空列表的情况,遗漏了空列表分支,传入空字符串时会触发运行时错误。
- 存在多余的空格判断逻辑,给定的需求用例中没有相关处理要求,属于冗余代码。
- 递归终止逻辑缺失:两个字符串逐字符比对到任意一方结束时,没有对应的返回逻辑。
修复后完整代码
match :: String -> String -> Maybe Char -- 任意一个字符串遍历完成,说明前缀全部相等,返回Nothing match [] _ = Nothing match _ [] = Nothing match (x:xs) (y:ys) | x /= y = Just x | otherwise = match xs ys
用例验证
match "alma" "alma"返回Nothing,符合预期match "alma" "asztal"返回Just 'l',符合预期match "asztal" "alma"返回Just 's',符合预期match "" ""返回Nothing,符合预期
内容的提问来源于stack exchange,提问作者topi12
相关产品推荐
相关产品推荐

