Haskell递归函数编写求助:双字符串匹配返回修改后列表
需求说明
需要实现一个函数,接收两个字符串(list1和list2),递归遍历list1并与list2的元素比较:当list1的元素与list2的首元素相等时终止递归,返回修改后的两个列表。例如输入list1="abcdef"、list2="def"时,应返回("def", "ef")。
问题代码与报错
当前编写的代码:
isEqual :: String -> String -> String ->String isEqual (s : os) (p : ps) | p /= s = isEqual os (p : ps) | otherwise = s:os ps
VS Code报错信息:
• Couldn't match expected type ‘String -> String’ with actual type ‘[Char]’
Possible cause: ‘(:)’ is applied to too many arguments
In the expression: s : os ps In an
equation for ‘isEqual’:
isEqual (s : os) (p : ps)
| p /= s = isEqual os (p : ps)
| otherwise = s : os pstypecheck(-Wdeferred-type-errors)• Couldn't match expected type ‘[Char] -> [Char]’
with actual type ‘[Char]’
The function ‘os’ is applied to one argument, but its type ‘[Char]’ has none
In the second argument of ‘(:)’, namely ‘os ps’
In the expression: s : os pstypecheck(-Wdeferred-type-errors)
错误原因分析
- 类型签名不匹配:原函数声明为
String -> String -> String -> String,但需求是返回两个字符串,正确的返回类型应为(String, String)元组。 - 语法逻辑错误:
s:os ps是非法写法,os是列表而非函数,不能直接传入参数ps;同时没有按照需求构造包含两个结果的元组。 - 缺失边界处理:未考虑
list1遍历完仍无匹配、或list2为空的场景,会导致递归无法终止或运行时错误。
修正后的代码
matchAndSplit :: String -> String -> (String, String) -- 处理list1遍历完仍无匹配的情况 matchAndSplit [] _ = ([], []) -- 处理list2为空的情况 matchAndSplit s [] = (s, []) matchAndSplit (s : os) (p : ps) | p /= s = matchAndSplit os (p : ps) | otherwise = (s : os, ps)
代码说明
- 类型签名:明确指定返回
(String, String)元组,符合返回两个列表的需求。 - 边界场景处理:
- 当
list1为空时,返回空元组(可根据实际需求调整,比如返回([], list2)); - 当
list2为空时,直接返回原list1和空列表。
- 当
- 递归逻辑:
- 若当前
list1元素与list2首元素不相等,递归遍历list1的剩余部分,list2保持不变; - 找到匹配元素时,返回
(list1从当前元素开始的剩余部分, list2去掉首元素后的剩余部分),正好满足示例输入的预期输出。
- 若当前
内容的提问来源于stack exchange,提问作者Energizer1

