是否存在“类型级组合器”?它们会在未来存在吗?
在我看来,haskell 真正好用的大部分原因是组合器,例如 (.)
、flip
、$
<* >
等等。感觉就像我可以在需要时创建新语法。
不久前,我正在做一些事情,如果我可以“翻转”类型构造函数,那将会非常方便。假设我有一些类型构造函数:
m :: * -> * -> *
并且我有一个类 MyClass
,它需要一个带有类型构造函数的类型 * ->; *。当然,我会选择以我可以做到的方式对类型进行编码:
instance MyClass (m a)
但是假设我无法更改该代码,并且假设真正适合 MyClass
的内容是这样的
type w b = m b a
instance MyClass w where
...
,然后我会必须激活XTypeSynonymInstances
。有没有办法创建一个“类型级别组合器”Flip
,这样我就可以这样做:
instance MyClass (Flip m a) where
...
??或者我们在 haskell 中使用的常见运算符的其他类型级别概括?这有用还是我只是在胡言乱语?
编辑:
我可以做类似的事情:
newtype Flip m a b = Flip (m b a)
newtype Dot m w a = Dot m (w a)
...
但是我必须使用数据构造函数 Flip
、Dot
、... 进行模式匹配等。值得吗?它?
Much of what makes haskell really nice to use in my opinion are combinators such as (.)
, flip
, $
<*>
and etc. It feels almost like I can create new syntax when I need to.
Some time ago I was doing something where it would be tremendously convenient if I could "flip" a type constructor. Suppose I have some type constructor:
m :: * -> * -> *
and that I have a class MyClass
that needs a type with a type constructor with kind * -> *
. Naturally I would choose to code the type in such a way that I can do:
instance MyClass (m a)
But suppose I can't change that code, and suppose that what really fits into MyClass
is something like
type w b = m b a
instance MyClass w where
...
and then I'd have to activate XTypeSynonymInstances
. Is there some way to create a "type level combinator" Flip
such that I can just do:
instance MyClass (Flip m a) where
...
?? Or other type level generalisations of common operators we use in haskell? Is this even useful or am I just rambling?
Edit:
I could do something like:
newtype Flip m a b = Flip (m b a)
newtype Dot m w a = Dot m (w a)
...
But then I'd have to use the data constructors Flip
, Dot
, ... around for pattern matching and etc. Is it worth it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的问题是有道理的,但答案是:不,目前不可能。
问题是(在 GHC Haskell 的类型系统中)你不能在类型级别使用 lambda。对于您可能尝试的任何看起来可以模拟或实现类型级别 lambda 效果的内容,您会发现它不起作用。 (我知道,因为我做到了。)
你可以做的是声明你的 Flip 新类型,然后编写你想要的类的实例,痛苦地进行包装和解包(顺便说一句:使用记录语法),然后类的客户端可以在类型签名中使用新类型,而不必担心细节。
我不是类型理论家,我不知道为什么我们不能拥有类型级别的 lambda 的详细信息。我认为这与类型推断变得不可能有关,但同样,我真的不知道。
Your question makes sense, but the answer is: no, it's not currently possible.
The problem is that (in GHC Haskell's type system) you can't have lambdas at the type level. For anything you might try that looks like it could emulate or achieve the effect of a type level lambda, you will discover that it doesn't work. (I know, because I did.)
What you can do is declare your Flip newtypes, and then write instances of the classes you want for them, painfully with the wrapping and the unwrapping (by the way: use record syntax), and then clients of the classes can use the newtypes in type signatures and not have to worry about the details.
I'm not a type theorist and I don't know the details of why exactly we can't have type level lambdas. I think it was something to do with type inference becoming impossible, but again, I don't really know.
您可以执行以下操作,但我认为它实际上不是很有用,因为您仍然无法真正部分应用它:
另请参阅之前的讨论:Haskell 中类型表达式的 Lambda?
You can do the following, but I don't think its actually very useful, since you still can't really partially apply it:
Also see this previous discussion: Lambda for type expressions in Haskell?
我在这里写答案只是为了澄清事情并讲述过去几年的成就。 Haskell 中有很多功能,现在您可以用类型编写一些运算符。使用 < code>$ 你可以这样写:
避免括号而不是老的
I'm writing answer here just for clarifying things and to tell about achievements in the last years. There're a lot of features in Haskell and now you can write some operators in type. Using
$
you can write something like this:to avoid parenthesis instead of good old