haskell - 在函数 Haskell 中创建一个变量
问题描述
我有两个字符串;一个主字符串,另一个是两个字符中的一个(例如“aa”)。
我想看看我的主字符串是否包含第二个字符串并在主字符串中打印它的索引。
我试图用自己压缩主字符串,这样我就可以检查一个接一个的字母的每个组合(例如“abab”=(a,b)(b,a)(a,b))。我用 [1..] 压缩这些元组以获得匹配字符串可能开始的正确索引((a,b)0)。然后我用 fst(fst h) 从元组中提取第一个字母,看看它是否与我的辅助字符串的第一个字母匹配。如果它没有找到任何匹配项,它应该在主字符串 (xs) 的其余部分上再次运行。我曾经where
将变量声明h
为head(locateZip x:xs)
locate (x:xs) (y:ys) = if fst(fst h) == y && snd(fst h) == ys then snd h else locate xs (y:ys)
where h = head(locateZip x:xs)
locateZip xs = zip(zip xs(tail xs)) [0..]
snd h
用于打印元组的索引。
它应该返回如下内容:
locate "aabba" "aa"
0
locate "bbaab" "aa"
2
我知道这可能看起来不寻常,但我还是新手,无法理解我得到的错误以及哪些有效,哪些无效。
我说错了h
:
Couldn't match expected type: ((Char, b2), b3) with actual type: [((b0, b0), b1)]
该where
语句是否正确用于此功能?
解决方案
我在您的代码中发现了三个问题。两个是语法问题,一个是逻辑问题。我试图尽可能少地改变。
首先,在 where 语句中,必须使用 () 和 ":" 运算符:
where h = head(locateZip (x:xs))
在您的代码中,Haskell 为 locateZip 函数推断出不同的类型。
二、在下面的对比中
snd(fst h) == ys
ys 是一个列表,而不是一个字符。这是因为“:”运算符将列表拆分为列表的第一个元素和列表的尾部,就像在函数的开头发生的那样:
locate (x:xs) (y:ys)
现在,逻辑问题。使用 where,只要调用 locate 函数,您就会生成一个 zip 列表。但是,无论何时调用 locateZip 函数,都会重新生成索引。然后,在您最初的想法中,只要找到该对,定位函数就会输出 0。
还有另一个问题,因为您的定位函数在开始时没有保护来停止递归。好吧,经过一些更改,下面的代码似乎可以按您的预期工作:
locate [] _ = -1
locate phrase pair = locate_aux phrase pair (locateZip phrase)
locate_aux _ _ [] = -1
locate_aux (x:xs) (y1:y2:ys) h =
if (fst (fst (head h)) == y1) && (snd (fst (head h)) == y2) then
snd (head h)
else
locate_aux xs (y1:y2:ys) (tail h)
locateZip xs = zip(zip xs(tail xs)) [0..]
推荐阅读
- mysql - 操作数应包含 1 列 if 子句
- oauth-2.0 - 如何在 Drupal 中集成 Oauth2 以进行用户登录?
- operator-keyword - Acumatica 在 BQL 中将 In <> 运算符用于整数
- javascript - 如何在 javascript/vuejs 中从孩子的 Id 中过滤父 json
- spring-boot - 在 WebFlux 中禁用 HTTP 缓存
- c# - Microsoft Graph:在 SharePoint 驱动器上搜索 DriveItems 不返回任何结果
- javascript - Angular 5 错误:无法绑定到“ngForFor”,因为它不是“li”的已知属性
- android - 将项目从 Android Studio 版本 2 转换为 3- 配置问题
- r - 使用 ggplot 将 Spotfire Rgraphs 转换为表格
- ios - AFNetworking:如何测量 HTTP 请求和响应时间?