编写类似构造函数的构造函数 [英] Composing type constructors like functions

查看:113
本文介绍了编写类似构造函数的构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到了一种情况,我希望能够在实例声明中编写类型构造函数。我希望这样做:

  instance(SomeClass t,SomeClass t')=> SomeClass(t。t')其中

(t。t') (t。t')a = t(t'a)(so t t'有类型 * - > * 我们可以部分应用类型构造函数,那么我们不能编写它们的原因是什么?另外,是否有可能解决我试图达到的目标?也许是平等约束?

(我知道 Control.Compose 存在,但它只是创建一个 newtype wrapper - 我想要一个类型同义词)。

解决方案

(我确实知道 Control.Compose 存在,但它只是创建了一个
newtype 包装器 - 我想要一个类型同义词)。

Haskell不允许这样做。一个类型同义词必须完全应用:你可以t写撰写t t',只有撰写t a'



允许部分应用的类型同义词会导致类型级别的lambda表达式,这会导致类型推断不可判定,因此在Haskell中缺少对它的支持。






例如(启用所有相关的GHC扩展)

  type Compose t t' a = t(t'a)
数据代理(k :: * - > *)=代理

pr ::代理(Compose [] [])
pr =代理

导致:

 类型同义词'Compose'应该有3个参数,但已经给出2 
在'pr'的签名中:pr :: Proxy(Compose [] [])

类似地,

  class C k其中f :: k Int  - > Int 
实例C(Compose [] [])其中f _ = 6



 类型同义词'Compose'应该有3个参数,但已经给出2 
在'C (Compose [] [])'

下面是一个示例,其中type synonym partial application / em>允许,而不是(允许 LiberalTypeSynonyms ):

  type T k = k Int 
type S = T(Compose [] [])

bar :: S - > S
bar = map(map succ)

请注意,这只适用于同义词之后我们得到一个完全应用类型 []([] Int)(即 [[Int]] )。粗略地说,这个功能不允许做任何没有它的工作,手动扩展同义词。


I recently came across a situation where I wanted to be able to compose type constructors in an instance declaration. I would have liked to do this:

instance (SomeClass t, SomeClass t') => SomeClass (t . t') where

with (t . t') defined such that (t . t') a = t (t' a) (so t and t' have kind * -> *. We can partially apply type constructors, like functions, so what is the reason we cannot compose them? Also, is there perhaps a workaround for what I was trying to achieve? Perhaps with equality constraints?

(I do know that Control.Compose exists, but it simply creates a newtype wrapper - I would like a type synonym).

解决方案

(I do know that Control.Compose exists, but it simply creates a newtype wrapper - I would like a type synonym).

This is not allowed in Haskell. A type synonym must be fully applied: you can't write Compose t t', only Compose t t' a.

Allowing partially applied type synonyms would lead to type-level lambdas, which makes type inference undecidable, hence the lack of support for it in Haskell.


For instance, (enabling all the relevant GHC extensions)

type Compose t t' a = t (t' a)
data Proxy (k :: * -> *) = Proxy

pr :: Proxy (Compose [] [])
pr = Proxy

results in:

 Type synonym ‘Compose’ should have 3 arguments, but has been given 2
    In the type signature for ‘pr’: pr :: Proxy (Compose [] [])

Similarly,

class C k where f :: k Int -> Int
instance C (Compose [] []) where f _ = 6

yields:

Type synonym ‘Compose’ should have 3 arguments, but has been given 2
    In the instance declaration for ‘C (Compose [] [])’

Here's an example where type synonym partial application is allowed, instead (enabling LiberalTypeSynonyms):

type T k = k Int
type S = T (Compose [] [])

bar :: S -> S
bar = map (map succ)

Note however that this works only because after synonym expansion we get a fully applied type [] ([] Int) (i.e., [[Int]]). Roughly, this feature does not allow to do anything which one could have done without it, manually expanding the synonyms.

这篇关于编写类似构造函数的构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆