List 比较两个列表中的某些元素,Haskell

List 比较两个列表中的某些元素,Haskell,list,haskell,functional-programming,pattern-matching,List,Haskell,Functional Programming,Pattern Matching,只是一个简短的免责声明我已经学习Haskell大约一个月了,一直在阅读、观看和搜索网络,但我就是无法理解这一点 所以我的问题是,我想比较两个字符串,比如“p16201348”和“p16202068”,基本上检查p后面的前两个数字是否是2016年的16。 在我下面的第一个例子中,我只是使用相同的列表进行比较。当我将其输入到ghci中时,它的计算结果将如您所期望的那样为true。我的问题是把它写成一个可调用函数 "p16201348" !! 1 == '1' && "p1620134

只是一个简短的免责声明我已经学习Haskell大约一个月了,一直在阅读、观看和搜索网络,但我就是无法理解这一点

所以我的问题是,我想比较两个字符串,比如“p16201348”和“p16202068”,基本上检查p后面的前两个数字是否是2016年的16。 在我下面的第一个例子中,我只是使用相同的列表进行比较。当我将其输入到ghci中时,它的计算结果将如您所期望的那样为true。我的问题是把它写成一个可调用函数

"p16201348" !! 1 == '1' && "p16201348" !! 1 == '1' && "p16201348" !! 2 == '6' && "p16201348" !! 2 == '6'
下面是我编写函数的第一次尝试,因为我说过p是不相关的,所以据我所知,我将列表分割为x:xs,而不考虑最终为:xs和:ys的头。当我试着打电话给它的时候,我得到了模棱两可的结果

compare (_:xs) (_:ys) = xs !! 1 == '1' && ys !! 1 == '1' && xs !! 2 == '6' && ys !! 2 == '6'
我的最后一个函数(protptype)是使用一个受保护的等式,尽管我甚至不知道是否可以拆分一个列表,然后对其中的某些元素求值

compare (_:xs)(_:ys)
    | xs !! 1  == '1' && ys !! 1 == '1' &&  xs !! 2  == '6' &&  ys !! 2 == '2' = "Same Year"
    | otherwise = "Different year"

提前感谢您的帮助。

我们可以通过执行模式匹配部分中已有的相等性检查,使其更加优雅。此外,您的函数缺少数字不相等的情况,或者当我传递无效字符串时

例如,对于年度
“16”
案例,我们可以使用:

-- only works for the year 16
compare (_:'1':'6':_) (_:'1':'6':_) = "Same year"
compare _ _ = "Different year"
因此,第一行检查列表的第二个和第三个元素是否分别是
'1'
'6'
。只有在这种情况下,我们才会返回“同一年”。在所有其他情况下(第二行),我们返回
“不同的年份”
。如果其中一个字符串少于三个字符,或者两个字符串至少有三个字符,但第二个和第三个字符分别不是
'1
'和/或
'6'
,则最后一行将触发

现在,如果我们想将其推广到任何一年,我们可以使用变量:

compare (_:x1:x2:_) (_:y1:y2:_) = ...
compare _ _ = "Different year"
因此这里
x1
是第一个字符串的第二个字符,
x2
是同一字符串的第三个字符
y1
是第二个字符串的第二个字符,
y2
是第二个字符串的第三个字符

我们可能希望确保这些都是数字,以便检查:

import Data.Char(isDigit)

compare (_:x1:x2:_) (_:y1:y2:_) | all isDigit [x1, x2, y1, y2] = ...
compare _ _ = "Different year"
因此,现在我们可以保证,如果防护装置“触发”,则所有这些字符都是数字(在
0
9
范围内)。当然,我们还需要确定它们是否具有相同的值


我把椭圆(
)需要填写的内容留作练习,它基本上是对问题中代码的概括。

我们可以通过执行模式匹配部分中已经存在的相等性检查,使其更加优雅。此外,您的函数缺少数字不相等的情况,或者当我传递无效字符串时

例如,对于年度
“16”
案例,我们可以使用:

-- only works for the year 16
compare (_:'1':'6':_) (_:'1':'6':_) = "Same year"
compare _ _ = "Different year"
因此,第一行检查列表的第二个和第三个元素是否分别是
'1'
'6'
。只有在这种情况下,我们才会返回“同一年”。在所有其他情况下(第二行),我们返回
“不同的年份”
。如果其中一个字符串少于三个字符,或者两个字符串至少有三个字符,但第二个和第三个字符分别不是
'1
'和/或
'6'
,则最后一行将触发

现在,如果我们想将其推广到任何一年,我们可以使用变量:

compare (_:x1:x2:_) (_:y1:y2:_) = ...
compare _ _ = "Different year"
因此这里
x1
是第一个字符串的第二个字符,
x2
是同一字符串的第三个字符
y1
是第二个字符串的第二个字符,
y2
是第二个字符串的第三个字符

我们可能希望确保这些都是数字,以便检查:

import Data.Char(isDigit)

compare (_:x1:x2:_) (_:y1:y2:_) | all isDigit [x1, x2, y1, y2] = ...
compare _ _ = "Different year"
因此,现在我们可以保证,如果防护装置“触发”,则所有这些字符都是数字(在
0
9
范围内)。当然,我们还需要确定它们是否具有相同的值


我留下你必须填写的椭圆(
)作为练习,它基本上是问题中代码的概括。

再次感谢所有建议,非常感谢。 所以我发现了我的代码不起作用的原因,这是因为我使用了Haskell内置函数“compare”作为我的函数名。所以一旦我给他们重新命名,他们都退房了

我想澄清一下我的问题是, 比较id号的第二个和第三个元素,如P16201348。这些元素表示两个数字是否来自同一年,如16、17等

我使用的代码是

pnum::Eq a=>[a]->[a]->Bool

pnum(:xs)(:ys)=xs!!1==ys!!1&&xs!!2==ys!!二,

因此,我在每个列表的开头使用下划线,因为这个元素并不重要。然后比较所需的元素并检查它们是否相等

我的意思是,这可能不是最好和最有效的方法,所以请让我知道,如果你不这样认为


再次感谢所有的建议,非常感谢。 所以我发现了我的代码不起作用的原因,这是因为我使用了Haskell内置函数“compare”作为我的函数名。所以一旦我给他们重新命名,他们都退房了

我想澄清一下我的问题是, 比较id号的第二个和第三个元素,如P16201348。这些元素表示两个数字是否来自同一年,如16、17等

我使用的代码是

pnum::Eq a=>[a]->[a]->Bool

pnum(:xs)(:ys)=xs!!1==ys!!1&&xs!!2==ys!!二,

因此,我在每个列表的开头使用下划线,因为这个元素并不重要。然后比较所需的元素并检查它们是否相等

我的意思是,这可能不是最好和最有效的方法,所以请让我知道,如果你不这样认为

谢谢