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

rba*_*iro 5 reflection haskell hlist

我试过了

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

但它回来了

["()"]
Run Code Online (Sandbox Code Playgroud)

sin*_*yma 7

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

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

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

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


Joa*_*ner 5

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

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

而左边部分的类型是

map show :: Show a => [a] -> [String]
Run Code Online (Sandbox Code Playgroud)

所以要结合这些,类型变量bresp.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"]
Run Code Online (Sandbox Code Playgroud)

遗憾的是,没有办法实现您想要的:选择所有类型支持show实例的元素,因为该信息不可用fromDynamic.