Pregunta

Digamos que quiero crear un caso especial para una función que coincida con las cadenas que comienzan con el carácter 'Z'. Podría hacerlo fácilmente utilizando la coincidencia de patrones haciendo algo como lo siguiente:

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

Pero, ¿qué pasa si quiero hacer coincidir cadenas con un prefijo más largo? Digamos que quiero tener un caso especial para cadenas que comiencen con la palabra "tostador". ¿Cuál es la mejor manera de escribir un patrón para que coincida con esa cadena?

¿Fue útil?

Solución

myfunc ('t':'o':'a':'s':'t':'e':'r' : restOfString) = ...

El uso de una coincidencia de patrón normal funciona, pero se vuelve molesto a medida que la cadena de prefijo se alarga.

{-# LANGUAGE PatternGuards #-}
import Data.List
myFunc string | Just restOfString <- stripPrefix "toaster" string =
    -- do something special
myFunc string = -- do the default case here

Usar una función de biblioteca en lugar de una coincidencia de patrón es un poco más fácil de leer y escribir.

{-# LANGUAGE ViewPatterns #-}
import Data.List
myFunc (stripPrefix "toaster" -> Just restOfString) = -- do something special
myFunc string = -- do the default case here

Una extensión de sintaxis GHC 6.10 hace que este uso sea aún más natural.


Por supuesto, los dos últimos son completamente equivalentes, y podemos hacerlo (desordenadamente) sin ningún tipo de azúcar.

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)

Sin embargo, esas extensiones de sintaxis están destinadas a hacernos la vida más fácil.

Otros consejos

import Data.List

myFunc str | "toaster" `isPrefixOf` str = something restOfString
           | otherwise = somethingElse
    where Just restOfString = stripPrefix "toaster" str

La biblioteca dividida, http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html tiene muchas funciones para dividir cadenas con cadenas, incluida la coincidencia de prefijos. Puede que encuentres algo útil allí.

myfunc ('t' : 'o' : 'a' : 's' : 't' : 'e' : 'r' : restOfString)

Que yo sepa, no hay una sintaxis más concisa que esa.

Por supuesto, también puede verificar si la cadena comienza con el tostador en una cláusula de protección o si dentro del cuerpo de la función.

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

Este es el motivo por el que stripPrefix devuelve un tipo Maybe.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top