Haskell中的模式匹配字符串前缀

Haskell中的模式匹配字符串前缀,haskell,pattern-matching,Haskell,Pattern Matching,假设我想为匹配以字符“Z”开头的字符串的函数设置一个特例。我可以通过执行以下操作,使用模式匹配轻松完成此操作: myfunc ('Z' : restOfString) = -- do something special myfunc s = -- do the default case here 但是如果我想匹配前缀更长的字符串呢?假设我想要一个以单词“toaster”开头的字符串的特殊情况。编写模式以匹配这样的字符串的最佳方法是什么 myfunc ('t' : 'o' : 'a' : 's'

假设我想为匹配以字符“Z”开头的字符串的函数设置一个特例。我可以通过执行以下操作,使用模式匹配轻松完成此操作:

myfunc ('Z' : restOfString) = -- do something special
myfunc s = -- do the default case here
但是如果我想匹配前缀更长的字符串呢?假设我想要一个以单词“toaster”开头的字符串的特殊情况。编写模式以匹配这样的字符串的最佳方法是什么

myfunc ('t' : 'o' : 'a' : 's' : 't' : 'e' : 'r' : restOfString)
据我所知,没有比这更简洁的语法了

当然,您也可以只检查字符串是以guard子句中的toaster开头,还是在函数体中以
if
开头

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
GHC6.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
myFunc str =
  case stripPrefix "toaster" str of
     Just restOfString -> something restOfString
     Nothing -> somethingElse

这就是为什么stripPrefix返回一个Maybe类型。

我第一次想到了类似的东西,但是必须编写两次
“toaster”
似乎很愚蠢。一开始,编写和调用模板Haskell以达到预期的效果看起来非常简单。不过,我不是一个很确定的人。不幸的是,GHC没有实现模式拼接(据我所知,显然这很难),所以这是不可能的。
myFunc str =
  case stripPrefix "toaster" str of
     Just restOfString -> something restOfString
     Nothing -> somethingElse