是否可以编写一个函数isFunc :: a -> Bool
来确定任意值是否是一个函数(任何类型),以便
foo :: Int -> Int
bar :: Char -> Char -> Char
> isFunc foo
True
> isFunc bar
True
> isFunc 3
False
> isFunc 'a'
False
我正在使用Data.Dynamic,所以我无法事先确定类型。
答案 0 :(得分:11)
您要求的是什么以及您需要对Data.Dynamic
做些什么似乎是不同的事情。在使用fromDyn
/ fromDynamic
提取值之前,您需要知道确切的值类型。要确定Dynamic
是否包含函数值,您需要分析TypeRep
:
isFuncDynamic x = typeRepTyCon (dynTypeRep x) == typeRepTyCon (typeOf2 id)
(如果这不是最简洁的实现,请原谅我。)
答案 1 :(得分:10)
Parametricity说没有。类型
的唯一功能a -> Bool
是常数函数。
然而,通过一些特殊的多态性和更多的chutzpah,你可以这样做:
{-# LANGUAGE OverlappingInstances, FlexibleInstances #-}
class Sick x where
isFunc :: x -> Bool
instance Sick (a -> b) where
isFunc _ = True
instance Sick x where
isFunc _ = False
然后看起来你有
*Sick> isFunc 3
False
*Sick> isFunc id
True
但这似乎是一件奇怪的事情。结果Bool
会对您有什么用处?