Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function Haskell运行时错误:错误:序言。(!!):索引太大_Function_Haskell_Runtime Error_List Comprehension - Fatal编程技术网

Function 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))) (#==#)::字符串->字

我在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)))
(#==#)::字符串->字符串->布尔
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