Haskell: Conversions of polymorphic types

I wanted to write a library that can convert types between various isomorphic formats and from "subtypes" to "supertypes", for example using the following isomorphisms and injections:

(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 (Constant function)

Int ~> Integer

Int ~> Double

a ~> ()

… and nested combinations of that.

It works (by transforming the input type into a canonical isomorphic form, deeply applying the subtype injections and than de-canonicalizing to the result type), but mostly only for monotypes. Using a polymorphic type in a position that is reachable in the tree of type constructors going only through the constructors (->) , Either and (,) will lead to an "Ambiguous Type" error message because the overlapping type classes that determine which transformations are applied cannot be resolved, and that is good, because the type variable could possibly be instantiated to for example a pair type, and ignoring this would make the whole transformation incoherent.

How can I constrain a Type variable to be neither of the form (a -> b) nor of the form (a, b) nor of the form (Either ab) ? I tried this:

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)
 )

in order to constrain the polymorphic type variables, but it does not work, not even in the canonicalization stage. This is because the information contained in a ForallV constraint is apparently only available by instantiating it via the instV function, and this must be done manually at the expression level. Is there any way to teach GHC to automatically use the information of a Forall constraint? An alternative would be to wrap each value in the Identity functor, but I would prefer to be able to put a constraint on the variables.

链接地址: http://www.djcxy.com/p/43068.html

上一篇: 约束种类中的平等约束

下一篇: Haskell:多态类型的转换