是否存在“类型级组合器”?它们会在未来存在吗?

发布于 2024-12-18 03:09:24 字数 976 浏览 1 评论 0原文

在我看来,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)

...

但是我必须使用数据构造函数 FlipDot、... 进行模式匹配等。值得吗?它?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

坏尐絯 2024-12-25 03:09:24

你的问题是有道理的,但答案是:不,目前不可能。

问题是(在 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.

晨光如昨 2024-12-25 03:09:24

您可以执行以下操作,但我认为它实际上不是很有用,因为您仍然无法真正部分应用它:

{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
module Main where

class TFlip a where
    type FlipT a

instance TFlip (f a b) where
    type FlipT (f a b) = f b a 

-- *Main> :t (undefined :: FlipT (Either String Int))
-- (undefined :: FlipT (Either String Int)) :: Either Int [Char]

另请参阅之前的讨论: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:

{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
module Main where

class TFlip a where
    type FlipT a

instance TFlip (f a b) where
    type FlipT (f a b) = f b a 

-- *Main> :t (undefined :: FlipT (Either String Int))
-- (undefined :: FlipT (Either String Int)) :: Either Int [Char]

Also see this previous discussion: Lambda for type expressions in Haskell?

鹿! 2024-12-25 03:09:24

我在这里写答案只是为了澄清事情并讲述过去几年的成就。 Haskell 中有很多功能,现在您可以用类型编写一些运算符。使用 < code>$ 你可以这样写:

foo :: Int -> Either String $ Maybe $ Maybe Int

避免括号而不是老的

foo :: Int -> Either String (Maybe (Maybe Int))

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:

foo :: Int -> Either String $ Maybe $ Maybe Int

to avoid parenthesis instead of good old

foo :: Int -> Either String (Maybe (Maybe Int))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文