比较两个列表的某些元素,Haskell
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了比较两个列表的某些元素,Haskell相关的知识,希望对你有一定的参考价值。
只是一个快速的免责声明我一直在学习Haskell大约一个月,一直在阅读,观看和搜索网络,但我不能理解这一点。
所以我的问题是,我想比较两个字符串说“p16201348”和“p16202068”并且基本上检查p之后的前两个数字是从2016年到16年。在我的下面的第一个例子中我只是使用相同的列表进行比较。当我将其输入到ghci时,它会按照您的预期评估为true。我的问题实际上是把它写成一个可调用的函数。
"p16201348" !! 1 == '1' && "p16201348" !! 1 == '1' && "p16201348" !! 2 == '6' && "p16201348" !! 2 == '6'
我写下这个函数的第一次尝试是在下面,因为我说p是无关紧要的,所以根据我的理解,我将列表拆分为x:xs butt忽略了头部,最终是_:xs和_:ys。当我试着调用它时,我得到了模棱两可的事件。
compare (_:xs) (_:ys) = xs !! 1 == '1' && ys !! 1 == '1' && xs !! 2 == '6' && ys !! 2 == '6'
我的最终功能(原型)是使用一个守卫方程,虽然我甚至不起诉如果可以拆分列表然后评估其中的某些元素
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'
。只有在那种情况下我们才会返回"Same year"
。在所有其他情况下(第二行),我们返回"Different year"
。因此,如果其中一个字符串少于三个字符,或者两个字符串至少有三个字符,但第二个和第三个字符分别不是'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”作为我的函数名。所以,一旦我将它们命名,它们就会结账。
只是为了澄清我的问题是,比较一个身份证号码的第二和第三个元素,例如P16201348。这些元素表示两个数字是否来自同一年,16,17等。
我带的代码就是这个,
pnum :: Eq a => [a] - > [a] - > Bool
pnum(:xs)(:ys)= xs !! 1 == ys !! 1 && xs !! 2 == ys !! 2
所以,我在每个列表的头部使用下划线,因为这个元素并不重要。然后我比较我需要的元素并检查它们是否相等。
我的意思是这可能不是最好和最有效的方法,所以如果你不这样做,请告诉我。
谢谢
以上是关于比较两个列表的某些元素,Haskell的主要内容,如果未能解决你的问题,请参考以下文章