Determine whether a value is a function in Haskell
Pergunta
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.
Solução
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?
Outras dicas
What are you asking for and what you need to do with Data.Dynamic
seem to be different things. You need to know the exact type of value before extracting it with fromDyn
/fromDynamic
. To determine whether Dynamic
contains a function value you need to analyze TypeRep
:
isFuncDynamic x = typeRepTyCon (dynTypeRep x) == typeRepTyCon (typeOf2 id)
(Forgive me if this is not the most concise implementation.)