Function Haskell运行时错误:错误:序言。(!!):索引太大
我在Haskell中有一个很长而且有点古怪的函数Function Haskell运行时错误:错误:序言。(!!):索引太大,function,haskell,runtime-error,list-comprehension,Function,Haskell,Runtime Error,List Comprehension,我在Haskell中有一个很长而且有点古怪的函数 (#==#) :: String -> String -> Bool str1 #==# str2 = (sum[ 1 | index <- [0..(max (length str1) (length str2))], (str1!!index == str2!!index || str1!!index == '$')] == (max (length str1) (length str2))) (#==#)::字符串->字
(#==#) :: String -> String -> Bool
str1 #==# str2 = (sum[ 1 | index <- [0..(max (length str1) (length str2))], (str1!!index == str2!!index || str1!!index == '$')] == (max (length str1) (length str2)))
(#==#)::字符串->字符串->布尔
str1#=#str2=(和[1 |索引让总计=(和[1 |索引总计
***例外:前奏曲。(!!):索引太大
我一直在做研究,但还没有找到解决这个错误的方法。如果有人知道这方面的任何事情,我将不胜感激
(顺便说一句,错误中的“索引”与我在函数中使用的索引不同)返回
!!
执行此任务意味着您试图将不同的语言硬塞进Haskell。请允许我为您指出一种更为Haskell的解决方案。据我所知,此函数执行标准的字符串相等性测试,但允许第一个字符串包含字符$
,这是一个可以匹配任何单个字符的“通配符”
回想一下,Haskell中的String
不过是一个Char
列表。因此,我们可以在两个列表构造函数上进行模式匹配:空列表和非空列表。两个列表的两种可能性的匹配为我们提供了四种可能的组合:
(#==#) :: String -> String -> Bool
[] #==# [] = ???
(x:xs) #==# [] = ???
[] #==# (y:ys) = ???
(x:xs) #==# (y:ys) = ???
考虑两个列表是否都是空的。它们匹配吗?当然,它们匹配。这是一个重要的基本情况选择,但现在我只想强调一个事实,将空字符串放入原始代码中应该会产生True
[] #==# [] = True
让我们看看中间两种情况,其中一个列表是空的,而另一个不是空的
(x:xs) #==# [] = ???
[] #==# (y:ys) = ???
您从未指定长度不均匀的列表应该发生什么。但是,为了保留您原来的算法,如果第一个列表中填充了$
,则我们称之为良好,否则,它就不匹配。因此,我们将检查左侧列表的第一个元素,如果它是$
,则我们将继续检查e名单的其余部分
('$':xs) #==# [] = xs #==# []
(x:xs) #==# [] = False
[] #==# (_:_) = False
让我们来看一个有趣的例子,两个都是非空的
(x:xs) #==# (y:ys) = ???
如果左边的第一个字符是$
,那么我们忽略右边的字符,并继续检查。如果绑定到x
和y
的字符相等,那么我们再次继续检查。如果它们不相等,那么我们将以False
停止
('$':xs) #==# (_:ys) = xs #==# ys
(x:xs) #==# (y:ys)
| x == y = undefined {- exercise to the reader -}
| otherwise = False
这项技术使用原始递归,而不是列表理解。如果这对您来说不太熟悉,那么我强烈建议您回顾一下Haskell方法的介绍。
I
涉及最长字符串的长度,呃?那么当您尝试在大索引中取消对较短字符串的引用时会发生什么呢?还有,最后一个有效的索引是长度列表-1
@Imray,用两个不同长度的字符串尝试一下…!!
是将其他语言的索引错误移植到Haskell的有效方法。(该代码看起来很像翻译成列表的for循环。)
('$':xs) #==# (_:ys) = xs #==# ys
(x:xs) #==# (y:ys)
| x == y = undefined {- exercise to the reader -}
| otherwise = False