I'd like to write a function that takes both
- a value constructor for a certain algebraic data type, and
- an actual value of that same type,
and determines whether the given value is "made from" the given constructor. Pattern matching seems like a natural fit for this, but the pattern to match against would have to be a function parameter instead of a hard-coded constructor name.
The code below is what I've tried, but GHC reports a parse error on the line indicated.
Is there a way to accomplish this?
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