Typeclass 使用接口定义类型上的部分函数

Typeclass 使用接口定义类型上的部分函数,typeclass,idris,type-level-computation,Typeclass,Idris,Type Level Computation,我试图在Idris中定义一些东西,它提供了一种以排版方式表示类型的方法。考虑一下Show,但是我想显示类型本身,而不是Showing类型的元素。这将产生与在类型上定义一个分部函数(它给出了一个类型的表示)相同的实际效果,用户也可以对其类型进行扩展 考虑到“用户可以扩展功能”的需求,我的第一个想法是使用接口。所以看起来是这样的: interface Representable a where representation : String 一些可能的实施将是必要的 Representable

我试图在Idris中定义一些东西,它提供了一种以排版方式表示类型的方法。考虑一下
Show
,但是我想显示类型本身,而不是
Show
ing类型的元素。这将产生与在
类型上定义一个分部函数(它给出了一个类型的表示)相同的实际效果,用户也可以对其类型进行扩展

考虑到“用户可以扩展功能”的需求,我的第一个想法是使用接口。所以看起来是这样的:

interface Representable a where
  representation : String
一些可能的实施将是必要的

Representable Nat where
  representation = "Nat"
然而,我遇到了一个问题。假设我想定义函数类型的表示形式。这将是其域的表示、箭头和范围的表示。大概是

(Representable a, Representable b) => Representable (a -> b) where
  representation = representation ++ " -> " ++ representation
问题现在显而易见。编译器无法推断右侧的
表示形式

我提出的一个替代方案是创建一个
表示
类型,该类型将携带一个“人工”参数:

data Representation : Type -> Type where
  Repr : (a : Type) -> String -> Representation a
这将导致

interface Representable a where
  representation : Representation a
然后

Representable Nat where
  representation = Repr Nat "Nat"

(Representable d, Representable r) => Representable (d -> r) where
  representation = Repr (d -> r) $
    (the (Representation d) representation)
    ++ " -> "
    ++ (the (Representation r) representation)
但后来,我错了

Representations.idr:13:20-127:
   |
13 |   representation = Repr (d -> r) $ (the (Representation d) representation) ++ " -> " ++ (the (Representation r) representation)
   |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When checking right hand side of Representations.Representations.d -> r implementation of Representations.Representable, method representation with expected type
        Representation (d -> r)

When checking argument a to constructor Representations.Repr:
        No such variable d
但是,我希望
表示
是无参数的,因为它是类型的表示,而不是其元素


是否有人对如何修复此特定错误有任何建议,或者更好的是,如何以一种不那么可怕的方式实现我的想法?

您可以从Haskell那里获得一个想法,并使用a将令牌传递给
表示,而不包含术语级内容:

data Proxy a = MkProxy

interface Representable a where
  representation : Proxy a -> String

Representable Nat where
  representation _ = "Nat"

(Representable a, Representable b) => Representable (a -> b) where
  representation {a = a} {b = b} _ = representation (MkProxy {a = a}) ++ " -> " ++ representation (MkProxy {a = b})