Строковые префиксы строк в Haskell
Скажем, я хочу сделать специальный случай для функции, которая соответствует строкам, начинающимся с символа "Z". Я мог бы легко сделать это, используя сопоставление шаблонов, выполнив что-то вроде следующего:
myfunc ('Z' : restOfString) = -- do something special
myfunc s = -- do the default case here
Но что, если я хочу сопоставить строки с более длинным префиксом? Скажем, я хочу иметь специальный случай для строк, которые начинаются со слова "тостер". Какой лучший способ написать шаблон для соответствия такой строке?
Ответы
Ответ 1
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)
Эти расширения синтаксиса предназначены для облегчения жизни для нас.
Ответ 2
import Data.List
myFunc str | "toaster" `isPrefixOf` str = something restOfString
| otherwise = somethingElse
where Just restOfString = stripPrefix "toaster" str
Ответ 3
Библиотека Split, http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html имеет много функций для разделения строк со строками, включая сопоставление префикса. Вы можете найти там что-то полезное.
Ответ 4
myfunc ('t' : 'o' : 'a' : 's' : 't' : 'e' : 'r' : restOfString)
Насколько мне известно, нет более сжатого синтаксиса.
Вы можете, конечно, также просто проверить, начинается ли строка с тостером в защитном предложении или if
внутри тела функции.
Ответ 5
myFunc str =
case stripPrefix "toaster" str of
Just restOfString -> something restOfString
Nothing -> somethingElse
Вот почему stripPrefix возвращает тип Maybe.