numero - Patrón de coincidencia de prefijos de cadena en Haskell
multiplos en haskell (5)
La biblioteca Split, 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í.
Digamos que quiero hacer un caso especial para una función que coincida con las cadenas que comienzan con el carácter ''Z''. Podría hacerlo fácilmente usando la coincidencia de patrones haciendo algo como lo siguiente:
myfunc (''Z'' : restOfString) = -- do something special
myfunc s = -- do the default case here
Pero, ¿y si quiero unir cadenas con un prefijo más largo? Digamos que quiero tener un caso especial para cadenas que comiencen con la palabra "tostadora". ¿Cuál es la mejor manera de escribir un patrón para que coincida con tal cadena?
import Data.List
myFunc str | "toaster" `isPrefixOf` str = something restOfString
| otherwise = somethingElse
where Just restOfString = stripPrefix "toaster" str
myFunc str =
case stripPrefix "toaster" str of
Just restOfString -> something restOfString
Nothing -> somethingElse
Esta es la razón por la que stripPrefix devuelve un tipo Maybe.
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 cuerda comienza con el tostador en una cláusula de protección o if
dentro del cuerpo de la función.
myfunc (''t'':''o'':''a'':''s'':''t'':''e'':''r'' : restOfString) = ...
Usar 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 hacer (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.