Haskell:显示所有的元素;“可展示”;在名单上

Haskell:显示所有的元素;“可展示”;在名单上,haskell,reflection,hlist,Haskell,Reflection,Hlist,我试过了 map show . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn ()] 但是它回来了 ["()"] 问题是fromDynamic必须为单态类型。它正在选择(),但是通过类型签名,您可以让它选择任何其他类型 要显示它,您需要一些函数依次尝试所有可能的类型。可能您不希望这样存储数据,而是希望将其与一些操作(如show)捆绑起来存储 有两种方法可以捆绑。我最喜欢的是将所

我试过了

map show . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn ()]
但是它回来了

["()"]

问题是
fromDynamic
必须为单态类型。它正在选择
()
,但是通过类型签名,您可以让它选择任何其他类型

要显示它,您需要一些函数依次尝试所有可能的类型。可能您不希望这样存储数据,而是希望将其与一些操作(如show)捆绑起来存储

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


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

您的代码并没有达到您期望的效果。早在
Data.dynamic
的动态行为开始之前,Haskell类型检查器就解析了这些类型。表达式右侧部分的类型为

mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn ()] :: Typeable b => [b]
左边部分的类型是

map show :: Show a => [a] -> [String]
因此,要组合这些变量,类型变量
b
resp<代码>一个得到统一。如果要从常规Haskell文件编译此文件,编译器会给您一个警告(
类型变量'a'为ambigous
)。但在GHCi中,解释器只是默认为
()

但这将表达式中的
类型从Dynamic
固定为
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

好主意:“将其与一些操作捆绑起来存储”您真的需要将数据混合存储在这样的列表中吗?例如,您可以使用记录更轻松地存储该数据,并且您可以轻松地使用元素上的show之类的函数,因为这些类型在运行时可用。在运行时固定类型是一个优点,而不是缺点,所以您应该尽可能地这样做。我正在从事的项目是github.com/rbarreiro/farofias。项目的下一步是添加函数,这些函数不是Data.Data的实例。