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?

其他提示

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top