Haskell:多态类型的转换
我想写一个库,可以在各种同构格式之间转换类型,并从“子类型”转换为“超类型”,例如使用以下同构和注入:
(a, (b, c))
- ((a, b), c)
(Either a (Either bc))
(Either (Either ab) c)
(a, ())
a
((), a)
(Either a Void)
a
(Either Void a)
(a, Void)
Void
(Void, a)
((a, b) -> c)
→ a -> (b -> c)
(() -> c)
c
(a, Either xy)
Either (a, x) (a, y)
(Either xy, a)
Either (x, a) (y, a)
a
〜> x -> a
(恒定函数)
Int
> Integer
Int
> Double
a
〜> ()
...和嵌套组合。
它的工作原理(通过将输入类型转换为规范的同构形式,深度应用子类型注入以及对结果类型进行反规范化),但大多只适用于单形。 在类型构造函数的树中只能通过构造函数(->)
访问的位置中使用多态类型时, Either
和(,)
将导致“Ambiguous Type”错误消息,因为重叠类型类会确定哪些变换应用程序无法解析,这是很好的,因为类型变量可能被实例化为例如对类型,而忽略它会使整个变换不连贯。
我如何限制一个Type变量既不是形式(a -> b)
也不是形式(a, b)
也不是形式(Either ab)
? 我试过这个:
class BinaryTC tc x (r::Bool) a b | tc x a b -> r
instance {-# OVERLAPPING #-} (r~'False) => BinaryTC tc (tc a b) r a b
instance {-# OVERLAPPABLE #-} (r~'True) => BinaryTC tc x r a b
type NotHaskGenerating x = (
ForallV (BinaryTC (,) x 'False),
ForallV (BinaryTC (->) x 'False),
ForallV (BinaryTC Either x 'False)
)
为了约束多态类型变量,但它不起作用,即使在规范化阶段也是如此。 这是因为包含在ForallV
约束中的信息显然只能通过instV
函数实例化,并且必须在表达式级别手动完成。 有什么方法可以教GHC自动使用Forall
约束的信息吗? 另一种方法是将每个值包装在Identity
仿函数中,但是我希望能够对变量进行约束。
上一篇: Haskell: Conversions of polymorphic types
下一篇: GHC rewrite rule specialising a function for a type class