Haskell或特定编译器是否有类似于类型级lambda的东西(如果这是一个术语)?
具体而言,假设我有一个参数化类型Foo a b
,并且希望Foo _ b
成为Functor的一个实例。是否有任何机制可以让我执行类似于下面的操作
instance Functor (\a -> Foo a b) where
...
?
Haskell或特定编译器是否有类似于类型级lambda的东西(如果这是一个术语)?
具体而言,假设我有一个参数化类型Foo a b
,并且希望Foo _ b
成为Functor的一个实例。是否有任何机制可以让我执行类似于下面的操作
instance Functor (\a -> Foo a b) where
...
?
A
和类型构造函数F
,函数应用F A
也是一种类型,但没有比“这是F
应用于A
”更多的(类型级)信息。a -> b -> a
隐含地意味着forall a b. a -> b -> a
。 forall
在其范围内绑定类型变量,因此行为类似于lambda。如果我记得没有错,这大致上是System F中的“大写Lambda”。其他扩展程序放宽了上述限制,或提供了部分解决方法(参见:Oleg的类型技巧)。然而,在任何地方以任何方式几乎唯一不能做到的一件事情就是您所询问的,即使用匿名函数抽象引入新的绑定范围。
data Foo a b where ...
实际上是使用 Scala 3 语法定义了类型 lambda [a, b] => F[A,B]
。但是在 Haskell 中,Kind 为 * -> * -> *
的东西毕竟是一种类型 lambda,只是在 kind 级别上没有命名的类型变量而已。 - MaatDeamon来自 TypeCompose:
newtype Flip (~>) b a = Flip { unFlip :: a ~> b }
http://hackage.haskell.org/packages/archive/TypeCompose/0.6.3/doc/html/Control-Compose.html#t:Flip
如果一个东西接受两个参数并且是“Functor”,你可以将其成为双函子:
http://hackage.haskell.org/packages/archive/category-extras/0.44.4/doc/html/Control-Bifunctor.html
(或者,在之后的 category-extras 中,还有一种更通用的版本:http://hackage.haskell.org/packages/archive/category-extras/0.53.5/doc/html/Control-Functor.html#t:Bifunctor)
我不太喜欢自问自答这个想法,但是根据Freenode上#haskell频道的几位用户所说,Haskell没有类型级别的lambda表达式。
EHC(以及其可能的后继者UHC)具有类型级别的lambda表达式,但它们没有记录文档,也不如依赖类型语言中强大。我建议您使用依赖类型语言,例如Agda(类似于Haskell)或Coq(不同,但仍然在核心上是纯函数式的,并且可以惰性或严格地进行解释和编译!)但我对这些语言有偏见,对于您在这里所提出的要求来说,这可能是100倍以上的过度杀伤力!
data Foo a b = Foo a b
type FooR a b = Foo b a
instance Functor (FooR Int) where
...
即使使用了-XTypeSynonymInstances和-XFlexibleInstances,这也不起作用;GHC希望在实例头中完全应用类型同义词。可能有一些方法可以使用类型族来解决。
根据情况,您可以用“翻转”的方式替换原始类型定义,然后为“正确”的版本创建一个类型同义词。
来自
data X a b = Y a b
instance Functor (\a -> X a b) where ...
到
data XFlip b a = Y a b -- Use me for instance decalarations
type X a b = XFlip b a -- Use me for everything else
instance Functor XFlip where ...