haskell - 结合 Data.Dynamic 和类型类

标签 haskell dynamic typeclass

给定一个 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表明这 DynamicData.Dynamic 慢 2-3 倍在 base对于上面使用的小型宇宙。将 Universe 增加到 30 个类型的构造函数会使其慢 10 倍多一点。

新类型自动推导
open-typerep支持从少量预定义的表示类型创建 Universe。原则上应该可以使用 TemplateHaskell 自动派生新类型的表示,但是为 Witness 生成正确的实例会很棘手。和 PWitness因为这些取决于可用的其他实例。 ( WitnessShow 实例用于 Dynamic 。)

关于haskell - 结合 Data.Dynamic 和类型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22876370/

相关文章:

Haskell:Num 是如何保存的?

Haskell - 有一个函数返回一个空字符

haskell - 使用 nix 构建简单的 haskell 库

haskell - 在 NixOs 上安装 Haskell 软件包 Euterpea 失败

ios - 如何删除 UITableView 部分标题删除后创建的空间?

uitableview - UITableViewCell 中具有动态高度的多个 UILabels

dynamic - 为什么特征对象 vtables 包含大小和对齐方式?

haskell - 类型类默认值中的类型注释会导致 "could not deduce"类型错误

haskell - 字符串和 [a] 实例

haskell - 双胞胎的方法是什么?