Is it possible to write a function isFunc :: a -> Bool
to determine whether an arbitrary value is a function (of any kind) such that
foo :: Int -> Int
bar :: Char -> Char -> Char
> isFunc foo
True
> isFunc bar
True
> isFunc 3
False
> isFunc 'a'
False
I'm using Data.Dynamic so I can't determine the type in advance.
Parametricity says no. The only functions of type
a -> Bool
are constant functions.
However, with a bit of ad hoc polymorphism and a bit more chutzpah, you can do this:
{-# LANGUAGE OverlappingInstances, FlexibleInstances #-}
class Sick x where
isFunc :: x -> Bool
instance Sick (a -> b) where
isFunc _ = True
instance Sick x where
isFunc _ = False
and then it looks like you have
*Sick> isFunc 3
False
*Sick> isFunc id
True
But it does seem like a peculiar thing to do. What use is the resulting Bool
to you?