Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Pattern-matching" types in Haskell

I want a function f that acts as an increment on Ints and as an identity on all the other types. I tried to enable the TypeApplications extension and do this the most straight-forward way possible:

f :: forall a. a -> a
f @Int x = x + 1
f @_   x = x

But the extension does not enable such patterns:

<interactive>:6:1: error: Parse error in pattern: f @Int

Is there pattern-matching for types (or a similar mechanism) in Haskell?

like image 345
Zhiltsoff Igor Avatar asked Jan 26 '26 23:01

Zhiltsoff Igor


1 Answers

As stated, this is impossible to achieve in Haskell since it would violate one of the fundamental properties of parametric polymorphism known as "parametricity", which ensures that any polymorphic function satisfies a specific property knows as the "free theorem".

In particular, a terminating function of type forall a. a -> a must be the identity. There are no other possible implementations.

That being said, if we allow a constraint on type a, this becomes possible. Typically, run-time type-testing is done in Haskell through the Typeable type class:

f :: forall a. Typeable a => a -> a
f x = case eqT @a @Int of    -- Is a ~ Int ?
   Just Refl -> x + 1        -- If it is, we can add one.
   Nothing   -> x            -- Otherwise, return x as-is.

This requires a bunch of GHC extensions, and to import Data.Typeable.

like image 81
chi Avatar answered Jan 28 '26 23:01

chi