vorrei scrivere una funzione che prende entrambepattern matching dove il modello è basato su (funzione) parametro
- un costruttore valore per un certo tipo di dati algebrico, e
- un valore effettivo dello stesso tipo,
e determina se il valore dato è "fatto da" il costruttore indicato. La corrispondenza tra i motivi sembra essere naturale per questo, ma il modello con cui confrontarsi dovrebbe essere un parametro di funzione invece di un nome di costruttore hard-coded.
Il codice seguente è quello che ho provato, ma GHC segnala un errore di analisi sulla linea indicata.
C'è un modo per realizzare questo?
data FooBar = Foo Int | Bar String
-- Imagine that these are useful functions.
processInt :: Int -> String
processInt = show
processString :: String -> String
processString = id
-- This should take one of the above functions and adapt it to operate on
-- FooBar values of compatible "type". Values that match the given FooBar
-- constructor should be "unwrapped" and passed to the given function.
typeCheck :: (a -> FooBar) -> (a -> String) -> (FooBar -> Maybe String)
typeCheck constructor func fooBar = case fooBar of
(constructor x) -> Just (func x) -- GHC says "Parse error in pattern: constructor"
_ -> Nothing
-- Define processing functions that operate on FooBars.
processFoo :: FooBar -> Maybe String
processFoo = typeCheck Foo processInt
processBar :: FooBar -> Maybe String
processBar = typeCheck Bar processString
È una calcolatrice RPN (programma di esercitazione) che può avere una combinazione di diversi tipi (ad esempio numeri e stringhe) nello stack. La maggior parte delle funzioni che operano sullo stack inizieranno spuntando alcuni valori, verificando che siano del tipo giusto per l'operazione e riportando un errore in caso contrario. Sto cercando di calcolare quel tipo di controllo per evitare la duplicazione del codice. – Wyzard
Ah! Sarà molto più semplice se codifichi i tag del tipo come valori semplici (ad esempio, i valori di Int), anziché come funzioni di costruzione. Questo è ciò che rende il tuo esempio così complicato: la combinazione di modelli sulle funzioni è difficile. –
Grazie, prenderò in considerazione l'utilizzo di tag di tipo numerico. Dato che il mio set di tipi è relativamente limitato, potrei anche creare una famiglia di funzioni come 'typeCheckInt',' typeCheckString', ecc. Con il costruttore appropriato codificato in ciascuno di essi.Dato che questo è un programma di pratica, ho pensato di provare qualcosa di un po 'più impegnativo, ma suona come se avessi potuto masticare più di quanto possa masticare. Conosco i generici nel contesto di C++ e Java, ma non nel contesto di Haskell. – Wyzard