Search code examples
haskellpattern-matchingcallbyname

Haskell pattern matching inside parentheses


I would like to define a function that operates on an expression of a certain type, but has access to its internal structure, if it has one. For instance, f in what follows:

g :: a -> a -> a
g x y = y

f :: a -> a
f x'@(g x y) = x'
f _ = 1

(g x y) is of type a, so f should be able to take it as an argument, but the definition for f above can't be parsed by Haskell. I would like to define something like f to take advantage of call-by-name evaluation. Is there any way to do this in Haskell?


Solution

  • First, pattern matching is allowed only on patterns, i.e. expressions built from application, constructors, and variables (used at most once).

    Second, even if it were extended, your example is problematic because your g is not injective:

    case g x y of g a b -> a
    

    should be equal to, since g x y = y

    case y of g a b -> a
    

    but then a could be anything.

    If instead it happens that g is defined by an expression which could be a pattern, then GHC can allow using it as a pattern if you ask for it through the PatternSynonyms GHC extension.

    pattern G a b = ("hello", b, a)
    
    foo = case someTriple of
            G a b     -> use a b
            (s, x, y) -> ...
    
    bar = G 4 5       -- we can also use G as a function