Lambda用于Haskell中的类型表达式?

时间:2010-11-01 14:37:49

标签: haskell lambda

Haskell或特定的编译器是否有类似级别的lambdas(如果这甚至是一个术语)?

详细说明,我说参数化类型Foo a b并希望Foo _ b成为Functor的一个实例。是否有任何机制可以让我做类似于

的事情
instance Functor (\a -> Foo a b) where
...

7 个答案:

答案 0 :(得分:24)

虽然sclv回答了你的直接问题,但我会补充一点,“类型级lambda”的含义不止一个。 Haskell有各种类型的运算符,但没有一个真正表现为正确的lambdas:

  • 类型构造函数:引入新类型的抽象类型运算符。给定类型A和类型构造函数F,函数应用程序F A也是一个类型,但不包含“应用F的其他(类型级别)信息A”。
  • 多态类型:类似a -> b -> a的类型隐式表示forall a b. a -> b -> aforall绑定其范围内的类型变量,因此行为有点像lambda。如果记忆为我服务,这大致是系统F中的“资本lambda”。
  • 类型同义词:必须完全应用的有限形式的类型运算符,并且只能生成基类型和类型构造函数。
  • 类型类:本质上是从类型/类型构造函数到值的函数,能够检查类型参数(即,通过类型构造函数上的模式匹配,与常规函数模式匹配的方式大致相同)在数据构造函数上)并用于定义类型的成员谓词。这些行为在某些方面更像是常规函数,但非常有限:类型类不是可以操作的第一类实体,它们仅作为输入(不是输出)而仅作为输出操作(肯定没有输入)。
  • 功能依赖:除了一些其他扩展外,它们还允许类型类隐式生成类型作为结果,然后可以将其用作其他类型类的参数。仍然非常有限,例如无法将其他类型的类作为参数。
  • 类型系列:功能依赖关系的替代方法;它们允许以更接近常规值级函数的方式定义类型上的函数。但是,通常的限制仍然适用。

其他扩展放松了一些提到的限制,或提供部分解决方法(另请参阅:Oleg的类型hackery)。然而,你在任何地方都无法做到的一件事就是你所要求的,即引入一个带有匿名函数抽象的新绑定范围。

答案 1 :(得分:17)

来自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,你可以把它变成一个bifunctor:

http://hackage.haskell.org/packages/archive/category-extras/0.44.4/doc/html/Control-Bifunctor.html

(或者,在后来的类别中,更通用的版本:http://hackage.haskell.org/packages/archive/category-extras/0.53.5/doc/html/Control-Functor.html#t:Bifunctor

答案 2 :(得分:7)

我不喜欢回答我自己的问题,但显然,根据Freenode上#haskell上的几个人,Haskell没有类型级别的lambdas。

答案 3 :(得分:5)

EHC(也许还有其继承者,UHC)具有类型级别的lambda,但它们没有文档记录,也没有依赖类型语言那么强大。我建议您使用依赖类型的语言,例如Agda(类似于Haskell)或Coq(不同,但仍然是纯函数的核心,并且可以严格地解释和编译!)但是我对这些语言有偏见,这可能是你要求的100倍矫枉过正了!

答案 4 :(得分:2)

我所知道的最接近的类型lambda是通过定义类型同义词。在您的示例中,

data Foo a b = Foo a b

type FooR a b = Foo b a

instance Functor (FooR Int) where
...

但即使使用-XTypeSynonymInstances -XFlexibleInstances,这也行不通; GHC期望类型syn完全应用于实例头中。可能有一些方法可以用类型系列来安排它。

答案 5 :(得分:1)

是的,Gabe说的是,类型家庭对此有所回答:

http://www.haskell.org/haskellwiki/GHC/Type_families

答案 6 :(得分:0)

根据情况,您可以将原始类型定义替换为“翻转”版本,然后为“正确”版本创建类型同义词。

来自

super().save(*args, **kwargs)
send_email(self.document.url)

data X a b = Y a b

instance Functor (\a -> X a b) where ...