快速免责声明我一直在学习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'
我的最终功能(protptype)正在使用一个保护等式,尽管如果可以拆分列表然后评估其中的某些元素,我甚至不会起诉
compare (_:xs)(_:ys)
| xs !! 1 == '1' && ys !! 1 == '1' && xs !! 2 == '6' && ys !! 2 == '2' = "Same Year"
| otherwise = "Different year"
提前感谢您的帮助。
答案 0 :(得分:4)
我们可以通过在模式匹配部分中执行相等性检查来使其更加优雅。此外,您的函数缺少例如数字不相等的情况,或者当我传递无效字符串时。
例如对于"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
范围内)。但当然我们仍然需要确定它们具有相同的价值。
我留下你必须填写的椭圆(...
)作为练习,它基本上是对问题中代码的概括。
答案 1 :(得分:0)
再次感谢所有建议,非常感谢。 所以我发现为什么我的代码没有工作,这是因为我使用的是Haskell内置函数"比较"作为我的功能名称。所以,一旦我将它们命名,他们就会检查出来。
只是为了澄清我的问题, 比较第二个& id号的第三个元素,例如P16201348。这些元素表明两个数字是否来自同一年,16,17等。
我带的代码就是这个,
pnum :: Eq a => [a] - > [a] - >布尔
pnum(:xs)(:ys)= xs !! 1 == ys !! 1&& xs !! 2 == ys !! 2
所以,我在每个列表的头部使用下划线,因为这个元素并不重要。然后我比较我需要的元素并检查它们是否相等。
我的意思是这可能不是最好和最有效的方法,所以如果您不这样做,请告诉我。
由于