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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top