Question

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.

Was it helpful?

Solution

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?

OTHER TIPS

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.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top