correspondência de padrão prefixos de cordas em Haskell
-
05-07-2019 - |
Pergunta
Vamos dizer que eu quero fazer um caso especial para uma função que corresponde a strings que começam com o caractere 'Z'. Eu poderia facilmente fazê-lo usando correspondência de padrões, fazendo algo como o seguinte:
myfunc ('Z' : restOfString) = -- do something special
myfunc s = -- do the default case here
Mas o que se eu quiser corresponder cordas com um prefixo mais longo? Digamos que eu queira ter um caso especial para cadeias que começam com a palavra "torradeira". Qual é a melhor maneira de escrever um padrão para corresponder a tal corda?
Solução
myfunc ('t':'o':'a':'s':'t':'e':'r' : restOfString) = ...
Usando um normal obras padrão de jogo, mas fica incómodos como a cadeia de prefixo fica maior.
{-# LANGUAGE PatternGuards #-}
import Data.List
myFunc string | Just restOfString <- stripPrefix "toaster" string =
-- do something special
myFunc string = -- do the default case here
Usando uma função de biblioteca, em vez de uma correspondência de padrão é um pouco mais fácil de ler e escrever.
{-# LANGUAGE ViewPatterns #-}
import Data.List
myFunc (stripPrefix "toaster" -> Just restOfString) = -- do something special
myFunc string = -- do the default case here
A GHC 6,10 extensão sintaxe faz esse uso ainda mais natural.
É claro que os dois últimos são perfeitamente equivalentes e nós podemos fazer fazer (messily) sem nenhum açúcar em tudo.
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)
Estas extensões de sintaxe são destinadas a tornar a vida mais fácil para nós, apesar de tudo.
Outras dicas
import Data.List
myFunc str | "toaster" `isPrefixOf` str = something restOfString
| otherwise = somethingElse
where Just restOfString = stripPrefix "toaster" str
A biblioteca Split, http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html tem muitas funções para cordas de divisão com cordas, incluindo correspondência prefixo. Você pode encontrar algo útil lá.
myfunc ('t' : 'o' : 'a' : 's' : 't' : 'e' : 'r' : restOfString)
Tanto quanto sei, não há sintaxe mais sucinta do que isso.
Você pode também, naturalmente, apenas verificar se a string começa com a torradeira em um guarda-cláusula ou um if
dentro do corpo da função.
myFunc str =
case stripPrefix "toaster" str of
Just restOfString -> something restOfString
Nothing -> somethingElse
É por isso que stripPrefix retorna um tipo Talvez.