Строковые префиксы сопоставления с образцом в Haskell

StackOverflow https://stackoverflow.com/questions/1602243

  •  05-07-2019
  •  | 
  •  

Вопрос

Допустим, я хочу сделать специальный случай для функции, которая соответствует строкам, начинающимся с символа 'Z'. Я мог бы легко сделать это, используя сопоставление с образцом, выполнив что-то вроде следующего:

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

Но что, если я хочу сопоставить строки с более длинным префиксом? Скажем, я хочу иметь особый случай для строк, начинающихся со слова «тостер». Какой лучший способ написать шаблон для сопоставления с такой строкой?

Это было полезно?

Решение

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

Библиотека Split, 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 или if внутри тела функции.

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

Вот почему stripPrefix возвращает тип Maybe.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top