Haskell 在单个模式匹配中指定多个备选方案?
以下面的函数为例(该函数很无意义,但至少说明了我的问题) 由于Haskell 在单个模式匹配中指定多个备选方案?,haskell,pattern-matching,Haskell,Pattern Matching,以下面的函数为例(该函数很无意义,但至少说明了我的问题) 由于myFunction[]和myFunction x匹配产生相同的结果,是否可以将它们组合成一个模式匹配,而不是将每个模式都写在单独的行上并剪切/粘贴结果?类似于“或”操作数: 不是这样的,但是有两种方法可以用一个条款来写: myFunction' (_:xs@(_:_)) = foo xs -- note the changed order: `_:...` first, thus myFunction' _ = "result"
myFunction[]
和myFunction x
匹配产生相同的结果,是否可以将它们组合成一个模式匹配,而不是将每个模式都写在单独的行上并剪切/粘贴结果?类似于“或”操作数:
不是这样的,但是有两种方法可以用一个条款来写:
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
myFunction'(:xs@(:)))=foo-xs——注意更改的顺序:`:…`首先,因此
myFunction'\u=“result”--每隔一次输入都会得到“result”
myFunction“”xs | null$drop 1 xs=“result”--或“|[]并非如此,但有两种方法可以使用一个子句编写它:
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
myFunction'(:xs@(:)))=foo-xs——注意更改的顺序:`:…`首先,因此
myFunction'\u=“result”--每隔一次输入都会得到“result”
myFunction“”xs | null$drop 1 xs=“result”--或“|[]我应该告诉您,您的myFunction
实际上并没有进行打字检查。应该是这样的:
myFunction :: [a] -> String
myFunction [] = "result"
myFunction [x] = "result"
myFunction (_:xs) = myFunction xs
也就是说,你想做的事情可以通过警卫来实现:
myFunction :: [a] -> String
myFunction xs
| (null xs) || (length xs == 1) = "result"
| otherwise = myFunction (tail xs)
或者一个更有效的方法,您不必遍历整个列表:
myFunction :: [a] -> String
myFunction xs
| (null xs) || null (tail xs) = "result"
| otherwise = myFunction (tail xs)
我应该告诉你,你的myFunction
实际上并没有进行打字检查。应该是这样的:
myFunction :: [a] -> String
myFunction [] = "result"
myFunction [x] = "result"
myFunction (_:xs) = myFunction xs
也就是说,你想做的事情可以通过警卫来实现:
myFunction :: [a] -> String
myFunction xs
| (null xs) || (length xs == 1) = "result"
| otherwise = myFunction (tail xs)
或者一个更有效的方法,您不必遍历整个列表:
myFunction :: [a] -> String
myFunction xs
| (null xs) || null (tail xs) = "result"
| otherwise = myFunction (tail xs)
这个怎么样?又短又甜:
{-# LANGUAGE ViewPatterns #-}
myFunction ((<2) . length -> True) = "result"
myFunction _ = "other result"
这是无限列表的中断,但这应该不太难解决
最后,如果还启用了LambdaCase
扩展,甚至可以编写
{-# LANGUAGE ViewPatterns, LambdaCase #-}
myFunction (\case { []->True ; [x]->True ; _->False } -> True) = "result"
myFunction _ = "other result"
这变得不可读且容易出错(您必须确保\case
表达式是total!),但它确实将两种模式合并为一种模式,并且只有恒定的开销。请不要这样做:-)这个怎么样?又短又甜:
{-# LANGUAGE ViewPatterns #-}
myFunction ((<2) . length -> True) = "result"
myFunction _ = "other result"
这是无限列表的中断,但这应该不太难解决
最后,如果还启用了LambdaCase
扩展,甚至可以编写
{-# LANGUAGE ViewPatterns, LambdaCase #-}
myFunction (\case { []->True ; [x]->True ; _->False } -> True) = "result"
myFunction _ = "other result"
这变得不可读且容易出错(您必须确保\case
表达式是total!),但它确实将两种模式合并为一种模式,并且只有恒定的开销。请不要这样做:-)因为有多个备选解决方案,所以被接受的答案。我认为第一个解决方案是不正确的,因为(:xs)
也匹配[x]
。第三个解决方案可以使用.Accepted答案稍微简化,因为有多个备选解决方案。我认为第一个解决方案是不正确的,因为(:xs)
也匹配[x]
。第三个解决方案可以使用@williness稍微简化,并使用高效版本更新:P@WillNess更新了一个有效的版本:P