me gustaría escribir una función que toma tantocoincidencia de patrón donde el patrón se basa en un (función) parámetro
- un constructor valor para un determinado tipo de datos algebraico, y
- un valor real de ese mismo tipo,
y determina si el valor dado está "hecho de" el constructor dado. La coincidencia de patrones parece un ajuste natural para esto, pero el patrón para hacer coincidir tendría que ser un parámetro de función en lugar de un nombre de constructor codificado.
El código siguiente es lo que he intentado, pero GHC informa un error de análisis en la línea indicada.
¿Hay alguna manera de lograr esto?
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
Es una calculadora RPN (programa de práctica) que puede tener una mezcla de diferentes tipos (por ejemplo, números y cadenas) en la pila. La mayoría de las funciones que operan en la pila comenzarán mostrando algunos valores, verificando que sean del tipo correcto para la operación e informando un error si no es así. Estoy tratando de factorizar esa comprobación de tipos para evitar la duplicación de código. – Wyzard
¡Ah! Será mucho más fácil si codifica las etiquetas de tipo como valores simples (por ejemplo, valores 'Int'), en lugar de como funciones de constructor. Eso es lo que hace que tu ejemplo sea tan complicado: la coincidencia de patrones en las funciones es sencillamente difícil. –
Gracias, consideraré usar etiquetas de tipo numérico en su lugar. Como mi conjunto de tipos es relativamente limitado, también podría hacer una familia de funciones como 'typeCheckInt',' typeCheckString', etc. con el constructor apropiado codificado en cada una.Como se trata de un programa de práctica, pensé que podría intentar algo un poco más desafiante, pero parece que me he mordido más de lo que puedo masticar. Estoy familiarizado con los genéricos en el contexto de C++ y Java, pero no en el contexto de Haskell. – Wyzard