假设我想为一个匹配以字符'Z'开头的字符串的函数创建一个特例。我可以通过执行以下操作来轻松地使用模式匹配来完成它:
myfunc ('Z' : restOfString) = -- do something special
myfunc s = -- do the default case here
但是如果我想匹配具有更长前缀的字符串呢?假设我想要一个以“烤面包机”开头的字符串的特殊情况。编写模式以匹配这样一个字符串的最佳方法是什么?
答案 0 :(得分:35)
myfunc ('t':'o':'a':'s':'t':'e':'r' : restOfString) = ...
使用普通模式匹配有效,但随着前缀字符串变长而变得麻烦。
{-# LANGUAGE PatternGuards #-}
import Data.List
myFunc string | Just restOfString <- stripPrefix "toaster" string =
-- do something special
myFunc string = -- do the default case here
使用库函数而不是模式匹配更容易读写。
{-# LANGUAGE ViewPatterns #-}
import Data.List
myFunc (stripPrefix "toaster" -> Just restOfString) = -- do something special
myFunc string = -- do the default case here
GHC 6.10语法扩展使这种用法更加自然。
当然,后两者是完全相同的,我们可以完全没有任何糖(干净)。
import Data.List
myFunc string =
if restIsJust
then -- do something special
else -- do the default case here
where
(restIsJust, restOfString) =
case stripPrefix "toaster" string of
Just something -> (True, something)
Nothing -> (False, undefined)
这些语法扩展旨在让我们的生活更轻松。
答案 1 :(得分:8)
import Data.List
myFunc str | "toaster" `isPrefixOf` str = something restOfString
| otherwise = somethingElse
where Just restOfString = stripPrefix "toaster" str
答案 2 :(得分:5)
Split库http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html有许多用字符串拆分字符串的功能,包括前缀匹配。你可能会在那里找到有用的东西。
答案 3 :(得分:3)
myfunc ('t' : 'o' : 'a' : 's' : 't' : 'e' : 'r' : restOfString)
据我所知,没有比这更简洁的语法了。
您当然也可以检查字符串是以护卫条款中的烤面包机开始,还是以函数体内的if
开头。
答案 4 :(得分:3)
myFunc str =
case stripPrefix "toaster" str of
Just restOfString -> something restOfString
Nothing -> somethingElse
这就是stripPrefix返回Maybe类型的原因。