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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With