haskell - Haskell Newbie - 发生检查:无法构造无限类型:a ~ [a]
问题描述
我正在尝试制作一个带有 3 个参数的函数“tokenize”;主字符串,应该在自己的字符串中的字符字符串和要从字符串中删除的字符字符串。
tokenize :: String -> String -> String -> [String]
tokenize [] imp remm = []
tokenize str imp remm = let chr = (head str) in
if elem chr imp then ([chr] : (tokenize (tail str) imp remm))
else if (elem chr remm ) then (tokenize (tail str) imp remm)
else chr: (tokenize (tail str) imp remm)
我收到此错误消息:
Occurs check:
cannot construct the infinite type: a ~ [a]
Expected type: [a]
Actual type: [[a]]
解决方案
在您的表达式中,您使用两个子表达式:
[chr] : (tokenize (tail str) imp remm))
和
chr: (tokenize (tail str) imp remm)
两者不能相互协调,因为这意味着[chr]
并且chr
具有相同的类型,因此会出现错误。
通常在函数式编程中,参数以不同的顺序写入。tokenize imp remm str
确实,将其与imp
重要字符、remm
要删除的字符和要处理的字符串一起编写更有意义str
。
我们可以使用辅助函数来实现该功能go
。这里go
基本上应该考虑四种情况:
- 我们到达列表的末尾,因此返回一个带有空列表的单例列表;
- 第一个字符是要从输出中消除的东西,我们在字符串的尾部递归;
- 字符很重要,我们产生一个空列表,将字符包裹在列表中,并在尾部递归;和
- 如果以上所有内容都不适用,我们将在递归时将字符添加到我们检索到的列表的头部。
我们过滤掉空列表,例如当我们有两个连续的字符时可能会发生这种情况imp
。
例如:
tokenize :: [Char] -> [Char] -> String -> [String]
tokenize imp remm = filter (not . null) . go
where go [] = [[]]
go (x:xs) | elem x remm = go xs
| elem x imp = [] : [x] : go xs
| otherwise = let (y:ys) = go xs in (x:y) : ys
然后我们产生:
Prelude> tokenize "abc" "def" "defaabyesays"
["a","a","b","ys","a","ys"]
然而,通过单独的功能解决单独的问题可能会更好。例如,首先有一个从remm
等中删除字符的功能。这使您更容易理解和修复您的功能。
推荐阅读
- doctrine - Symfony 4:教义、关系和树枝
- .net - 在哪里可以下载 Informix ADO.NET 提供程序?
- mongodb - 删除 value 不是数组的文档
- php - 如何在php mysql中的td中的tr中加入表格并分别显示
- android - 所有 com.android.support 库必须使用完全相同的版本规范 gradle 错误
- python - 如何在 send_from_directory Flask 中给出绝对路径
- wordpress - 如何获取“ninja_forms_submit_data”和表单本身以返回错误响应?
- python - Django 1.7 ContentType 与应用程序
- javascript - 替换和 if/else
- php - 将字符串转换为二维数组并改组