[英]Specifying multiple alternatives in a single pattern match?
Take the following function as an example (the function is quite meaningless but at least illustrates my question). 以下面的函数为例(该函数毫无意义,但至少说明了我的问题)。
myFunction :: [x] -> x
myFunction [] = "result"
myFunction [x] = "result"
myFunction (_:xs) = myFunction xs
...
Since myFunction []
and myFunction x
matches produce the same result, is it possible to combine these into a single pattern-match rather than writing each one on a separate line and cut/pasting the result? 由于
myFunction []
和myFunction x
匹配产生相同的结果,是否可以将它们组合成单个模式匹配,而不是将每个写在单独的行上并剪切/粘贴结果? Something like an "OR" operand: 类似于“ OR”操作数:
myFunction [] || x = "result"
Not as such, but there are a couple of alternatives to write it with one clause: 并不是这样,但是有两个替代方法可以用一个子句来编写它:
myFunction' (_:xs@(_:_)) = foo xs -- note the changed order: `_:...` first, thus
myFunction' _ = "result" -- you'll get "result" for _every_ other input
myFunction'' xs | null $ drop 1 xs = "result" -- or `| [] <- drop 1 xs`
myFunction'' (_:xs) = foo xs
myFunction''' xs' = case drop 1 xs' of
[] -> result
xs -> foo xs
I should tell you that your myFunction
doesn't actually typecheck. 我应该告诉您,您的
myFunction
实际上没有进行类型检查。 It should be like this: 应该是这样的:
myFunction :: [a] -> String
myFunction [] = "result"
myFunction [x] = "result"
myFunction (_:xs) = myFunction xs
That being said, what you want to do can be achieved through guards: 话虽如此,您想做的事情可以通过警卫来实现:
myFunction :: [a] -> String
myFunction xs
| (null xs) || (length xs == 1) = "result"
| otherwise = myFunction (tail xs)
Or a more efficient one in which you don't have to traverse the entire list: 或者是一种更高效的方法,您不必遍历整个列表:
myFunction :: [a] -> String
myFunction xs
| (null xs) || null (tail xs) = "result"
| otherwise = myFunction (tail xs)
How about this? 这个怎么样? Short and sweet:
简短而甜美:
{-# LANGUAGE ViewPatterns #-}
myFunction ((<2) . length -> True) = "result"
myFunction _ = "other result"
You can replace (<2) . length
您可以替换
(<2) . length
(<2) . length
by any other function of type [a] -> Bool
, of course, including lambdas . [a] -> Bool
类型的任何其他函数的(<2) . length
,当然包括lambdas 。 As written, your example would probably be more precisely represented with first case 如前所述,您的示例可能用第一种情况更精确地表示
myFunction (\xs -> null xs || length xs == 1 -> True) = "result"
myFunction _ = "other result"
This is breaks for infinite lists, but that shouldn't be too hard to solve. 这是无限列表的突破口,但解决起来并不难。
Finally, if you also enable the LambdaCase
extension, you can even write 最后,如果您还启用了
LambdaCase
扩展程序,甚至可以编写
{-# LANGUAGE ViewPatterns, LambdaCase #-}
myFunction (\case { []->True ; [x]->True ; _->False } -> True) = "result"
myFunction _ = "other result"
That's getting unreadable and error prone (you have to make sure the \\case
expression is total! ) but it does combine two patterns into one, with only constant overhead. 这变得不可读并且容易出错(您必须确保
\\case
表达式是total!),但是它确实将两种模式组合为一个,而开销却是恒定的。 Don't do this, please :-) 不要这样做,请:-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.