假设我想为一个匹配以字符'Z'开头的字符串的函数创建一个特例。我可以通过执行以下操作来轻松地使用模式匹配来完成它:

myfunc ('Z' : restOfString) = -- do something special
myfunc s = -- do the default case here

但是如果我想匹配具有更长前缀的字符串呢?假设我想要一个特殊情况下的字符串以单词“toaster”开头。编写模式以匹配这样一个字符串的最佳方法是什么?

有帮助吗?

解决方案

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)

这些语法扩展旨在让我们的生活更轻松。

其他提示

import Data.List

myFunc str | "toaster" `isPrefixOf` str = something restOfString
           | otherwise = somethingElse
    where Just restOfString = stripPrefix "toaster" str

拆分库, http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html 有许多用字符串拆分字符串的功能,包括前缀匹配。你可能会在那里找到有用的东西。

myfunc ('t' : 'o' : 'a' : 's' : 't' : 'e' : 'r' : restOfString)

据我所知,没有比这更简洁的语法了。

您当然也可以检查字符串是以guard-clause中的多士炉开头还是以函数体内的 if 开头。

myFunc str =
  case stripPrefix "toaster" str of
     Just restOfString -> something restOfString
     Nothing -> somethingElse

这就是stripPrefix返回Maybe类型的原因。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top