有没有办法使这种类型的家庭具有内射性?

时间:2018-11-10 12:50:12

标签: haskell type-families

以下类型族

type family ListVariadic (as :: [Type]) (b :: Type) = (f :: Type) where  
  ListVariadic (a ': as) b = a -> ListVariadic as b
  ListVariadic '[]       b = b

显然不是单射的,例如ListVariadic '[] (a -> a) ~ ListVariadic '[a] a
但是,具有内射性来帮助进行类型推断非常方便,而且我不打算将ListVariadic的第二个参数用作函数类型。
我提出了两种解决方法,但都不太令人满意:

选项1:(通过类型类)传递见证了ListVariadic左逆的类型族。

type family Arguments (f :: Type) :: [Type] where
  Arguments (a -> b) = a ': Arguments b
  Arguments b        = '[]
type family Return (f :: Type) :: Type where
  Return (a -> b) = Return b
  Return b        = b

class    ( f ~ ListVariadic (Arguments f) (Return f) ) => VariadicIsInjective f where
instance ( f ~ ListVariadic (Arguments f) (Return f) ) => VariadicIsInjective f where

对我来说,这最终引入了太多的复杂性,不得不将这些辅助类型贯穿于整个线程中。

选项2。在可变参数类型族的定义中明确列出一个将要使用的所有非功能类型:

type family ListVariadic (as :: [Type]) (b :: Type) = (f :: Type) | f -> as b where  
  ListVariadic (a ': as) b = a -> ListVariadic as b
  ListVariadic '[] ()     = ()
  ListVariadic '[] Bool   = Bool
  ListVariadic '[] Word   = Word 
  ListVariadic '[] Int    = Int 
  ListVariadic '[] Float  = Float
  ListVariadic '[] Double = Double
  ... ... ...
  ListVariadic '[] (a,b) = (a,b)
  ListVariadic '[] (a,b,c) = (a,b,c)
  ... ... ...
  ListVariadic '[] [a] = [a]
  ... ... ...

然后,一个内注性注释是可能的,并且可以按预期工作。显然,它的局限性很强……并且最终仍然以a ~ ListVariadic '[] a形式的约束条件需要传递。


我希望有一种写ListVariadic类型族(或实现相同目的的东西)的方法,指出它的第二个参数不是函数,并允许插入性注释。
我知道我很麻烦,因为在提供的ListVariadic的第一个定义中,第二个等式在右侧有一个裸类型变量。通常在检查内射性时是不允许的...但是也许有一些使用类型同义词的巧妙技巧可以解决此问题?

0 个答案:

没有答案