Question

Supposons que je souhaite créer un cas spécial pour une fonction qui correspond aux chaînes commençant par le caractère 'Z'. Je pourrais facilement le faire en utilisant une correspondance de modèle en procédant comme suit:

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

Mais que faire si je veux faire correspondre les chaînes avec un préfixe plus long? Dites que je veux avoir un cas particulier pour les chaînes qui commencent par le mot "grille-pain". Quel est le meilleur moyen d’écrire un modèle pour correspondre à une telle chaîne?

Était-ce utile?

La solution

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

L'utilisation d'une correspondance de modèle normale fonctionne, mais devient gênante à mesure que la chaîne de préfixe s'allonge.

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

L'utilisation d'une fonction de bibliothèque au lieu d'une correspondance de modèle est un peu plus facile à lire et à écrire.

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

Une extension de syntaxe GHC 6.10 rend cette utilisation encore plus naturelle.

Bien sûr, les deux derniers sont complètement équivalents, et nous pouvons nous débrouiller sans aucun sucre.

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)

Ces extensions de syntaxe sont conçues pour nous simplifier la vie.

Autres conseils

import Data.List

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

La bibliothèque Split, http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html offre de nombreuses fonctions pour fractionner des chaînes avec des chaînes, y compris la correspondance du préfixe. Vous y trouverez peut-être quelque chose d'utile.

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

Autant que je sache, il n’existe pas de syntaxe plus succincte que celle-là.

Vous pouvez bien sûr aussi simplement vérifier si la chaîne commence par toaster dans une clause de garde ou un if dans le corps de la fonction.

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

C’est pourquoi stripPrefix renvoie un type Maybe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top