Domanda

Diciamo che voglio creare un caso speciale per una funzione che corrisponda a stringhe che iniziano con il carattere 'Z'. Potrei facilmente farlo usando il pattern matching facendo qualcosa di simile al seguente:

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

Ma cosa succede se voglio abbinare le stringhe con un prefisso più lungo? Supponiamo di voler avere un caso speciale per le stringhe che iniziano con la parola "tostapane". Qual è il modo migliore per scrivere un modello per abbinare una tale stringa?

È stato utile?

Soluzione

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

L'uso di una corrispondenza di pattern normale funziona, ma diventa fastidioso man mano che la stringa del prefisso si allunga.

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

L'uso di una funzione di libreria anziché di una corrispondenza di pattern è un po 'più facile da leggere e scrivere.

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

Un'estensione della sintassi di GHC 6.10 rende questo utilizzo ancora più naturale.


Naturalmente, gli ultimi due sono completamente equivalenti e possiamo accontentarci (in modo disordinato) senza zucchero.

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)

Quelle estensioni di sintassi sono pensate per semplificarci la vita.

Altri suggerimenti

import Data.List

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

La libreria Split, http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html ha molte funzioni per dividere le stringhe con le stringhe, inclusa la corrispondenza del prefisso. Potresti trovare qualcosa di utile lì.

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

Per quanto ne so, non esiste sintassi più concisa di quella.

Ovviamente puoi anche verificare se la stringa inizia con un tostapane in una clausola di protezione o un se all'interno del corpo della funzione.

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

Ecco perché stripPrefix restituisce un tipo Maybe.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top