You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell查找双字符子串索引时where定义变量报错问题求助

问题解答

首先明确:你的where语句语法使用完全正确,报错与where本身无关,问题出在表达式优先级解析和逻辑设计上。

报错原因

Haskell中函数调用的优先级高于列表构造运算符:,你写的locateZip x:xs会被编译器解析为(locateZip x) : xs,而非你预期的locateZip (x:xs)。
这就导致head接收的参数是一个嵌套列表,取出来的首元素仍然是列表类型,和你预期的((Char, Char), Int)类型不匹配,因此抛出了你遇到的类型错误。

其他需要修正的逻辑问题

  1. 索引计算错误:你每次递归传入切掉首字符的xs,但locateZip生成的索引永远从0开始,就算后续匹配成功,返回的索引也是相对于子串的偏移,和主串的实际索引不符。
  2. 类型不匹配:判断条件中的snd(fst h) == ys写法错误,ys是待匹配串的尾部(字符串类型),而snd(fst h)是Char类型,两者类型不同无法直接比较。
  3. 缺少边界处理:主串长度小于2时调用tail会直接崩溃,没有匹配结果时会无限递归最终报错。
修正方案

如果你想保留原本的zip实现思路,可以改成如下写法:

locate :: String -> String -> Int
locate mainStr pattern@[y1, y2] = case filter matchPair (locateZip mainStr) of
  [] -> error "未找到匹配子串"
  (_, idx):_ -> idx
  where
    locateZip xs = zip (zip xs (tail xs)) [0..]
    matchPair ((a, b), _) = a == y1 && b == y2
-- 处理待匹配串长度不为2的边界
locate _ _ = error "待匹配串长度必须为2"

运行验证

locate "aabba" "aa" 
-- 输出 0
locate "bbaab" "aa"
-- 输出 2

内容的提问来源于stack exchange,提问作者Anders Stene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 23:15:00