结合Data.Dynamic和类型类

Mik*_*cki 8 haskell dynamic typeclass

给定一个类型的变量Dynamic,它可以利用内部变量的类型类而不调整确切的类型?例如,假设我想编写一个函数prettyShow.如果内部类型是实例Show,那么我们应该使用该实例; 否则,我们应该使用Dynamic该类的实例.在代码中,这可能看起来像:

prettyShow :: Dynamic -> String
prettyShow x = case fromDynamic x :: (forall a. Show a => Maybe a) of
    Nothing -> show x
    Just y -> show y
Run Code Online (Sandbox Code Playgroud)

编辑:由于看起来这不能直接完成,有什么好的解决方法可以做到?

emi*_*son 6

这可以通过执行来实现Dynamic开放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
Run Code Online (Sandbox Code Playgroud)

定义show很简单,您可以使用库来定义动态值上的其他函数.

在上面的例子中,我使用了封闭式宇宙Type.但是,使用数据类型单点技巧,您还可以定义开放Universe的功能.例如,show它本身是开放的.

性能

简单的基准显示,这Dynamic是慢2-3倍Data.Dynamicbase上面所使用的小型的宇宙.将Universe增加到30个类型构造函数会使它慢一点多10倍.

自动派生新类型

open-typerep支持从少量预定义的表示类型中创建Universe.原则上应该可以使用TemplateHaskell自动派生新类型的表示,但是生成正确的实例Witness并且PWitness因为这些实例取决于可用的其他实例将是棘手的.(Witness例如由Show实例使用Dynamic.)