Haskell:显示Hlist上“可显示”的所有元素

时间:2013-02-04 21:22:30

标签: haskell reflection hlist

我试过了

map show . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn ()]

但它返回了

["()"]

2 个答案:

答案 0 :(得分:7)

问题是fromDynamic必须转变为单形类型。它正在挑选(),但是使用类型签名,您可以选择任何其他类型。

要显示它,您需要一些能够依次尝试所有可能类型的函数。可能你不想存储这样的数据,但是想要将它与一些操作(例如show)捆绑在一起。

您可以通过两种方式进行捆绑。我最喜欢的是将所有函数预先应用于值(因此对于show,您只需获得String类型的thunk列表。

另一种方法是将函数放入Dynamic(确保它们是正确的单态类型!)然后使用dynApply

答案 1 :(得分:5)

您的代码没有按照您的预期执行。早在Data.Dynamic的动态行为开始之前,Haskell类型检查器就会解析类型。表达式右侧部分的类型是

mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn ()] :: Typeable b => [b]

,左侧部分的类型是

map show :: Show a => [a] -> [String]

所以要结合这些,类型变量b和。 a统一了。如果您要从常规Haskell文件编译它,编译器会给您一个警告(The type variable `a' is ambigous)。但在GHCi中,解释器默认为()

但是,这会将表达式中fromDynamic的类型修复为Dynamic -> Maybe (),从而有效地选择()类型的所有元素。

如果强制编译器在那里使用其他类型,例如通过指定类型签名,您会看到fromDynamic选择其他类型:

Prelude Data.Dynamic Data.Maybe> map (show :: Integer -> String) . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn ()]
["3"]

不幸的是,没有办法达到你想要的效果:选择所有类型支持show实例的元素,因为fromDynamic无法获得该信息。