给定一个 Dynamic
类型的变量,是否可以在不以确切类型为条件的情况下利用内部变量的类型类?例如,假设我要写一个函数 prettyShow
.如果内部类型是 Show
的实例,那么我们应该使用那个实例;否则,我们应该使用 Dynamic
的实例类(class)。在代码中,这可能如下所示:
prettyShow :: Dynamic -> String
prettyShow x = case fromDynamic x :: (forall a. Show a => Maybe a) of
Nothing -> show x
Just y -> show y
编辑:既然这似乎不能直接完成,有什么好的解决方法可以做到?
最佳答案
这可以使用 Dynamic
的实现来完成。在 open-typerep库(如果您接受使用通用编程和大量 GHC 扩展)。
{-# LANGUAGE TypeOperators #-}
import Data.TypeRep
type Types = BoolType :+: IntType :+: ListType
x, y :: Dynamic Types
x = toDyn [False,True]
y = toDyn [1, 2 :: Int]
test1 = show x
test2 = show y
show
的定义很简单,您可以使用该库在动态值上定义其他函数。在上面的例子中,我使用了一个封闭类型的 Universe
Type
.但是使用 Data Types à la Carte 技巧,您还可以为开放宇宙定义函数。例如,show
本身是开放的。业绩
一个 simple benchmark表明这
Dynamic
比 Data.Dynamic
慢 2-3 倍在 base
对于上面使用的小型宇宙。将 Universe 增加到 30 个类型的构造函数会使其慢 10 倍多一点。新类型自动推导
open-typerep
支持从少量预定义的表示类型创建 Universe。原则上应该可以使用 TemplateHaskell 自动派生新类型的表示,但是为 Witness
生成正确的实例会很棘手。和 PWitness
因为这些取决于可用的其他实例。 ( Witness
被 Show
实例用于 Dynamic
。)
关于haskell - 结合 Data.Dynamic 和类型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22876370/