为什么 GHCi 无法解析 [[]] 类型?

发布于 2024-09-05 05:43:14 字数 101 浏览 7 评论 0原文

为什么 Haskell 无法解析 [[]](列表的列表)类型?
为什么不简单地 * -> *,因为我可以给它一个像 Int 这样的类型,并得到 [[Int]],这是一种 *.

Why can't Haskell resolve the kind of [[]] (A list of lists)?
Why isn't it simply * -> *, as I can give it a type like Int, and get [[Int]], which is of kind *.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

眼眸里的那抹悲凉 2024-09-12 05:43:14

我认为这与 Maybe Maybe 相同,尽管在后一种情况下,原因可能更清楚:“外部”类型构造函数期望传递一种 * 类型,但看到类型构造函数 * -> * (“内部”也许 / [])并抱怨。如果我是正确的,这实际上并不是 GHCi 的 :kind 功能的问题,而是找到正确的语法来表达更高级类型构造函数的组合的问题。

作为一种解决方法,

:kind forall a. [[a]]
:kind forall a. Maybe (Maybe a)

可以使用类似的东西(我认为打开适当的语言扩展 - ExistentialQuantification - 以启用 forall 语法)。

I think it's the same as with Maybe Maybe, although in the latter case the reason is perhaps clearer: the "outer" type constructor expects to be passed a type of kind *, but sees a type constructor of type * -> * (the "inner" Maybe / []) and complains. If I'm correct, this is not really a problem with the :kind functionality of GHCi, but rather with finding the correct syntax to express the composition of higher-kinded type constructors.

As a workaround, something like

:kind forall a. [[a]]
:kind forall a. Maybe (Maybe a)

can be used (with the appropriate language extension turned on -- ExistentialQuantification, I think -- to enable the forall syntax).

简美 2024-09-12 05:43:14

如果我们将 [[]] 脱糖为 [] [] ,那么很明显它的种类很差,因为 [] :: * -> *。

如果您实际上想要一个“列表的列表”,您需要编写两个 * -> 类型的构造函数。 *。如果没有一些样板文件,你就无法做到这一点,因为 Haskell 没有类型级 lambda。不过,您可以这样做:

newtype Comp f g a = Comp { unComp :: f (g a) }

现在您可以编写:

type ListList = Comp [] []

并使用它编写函数:

f :: ListList Int -> ListList Int
f = Comp . map (map (+1)) . unComp

像这样的函子组合在多个领域都有应用,尤其是 Swierstra 的 "数据类型点菜"

If we desugar [[]] as [] [] then it's obvious that it is poorly kinded because [] :: * -> *.

If you actually wanted a "list of lists" you need to compose two type constructors of kind * -> *. You can't do that without a little boilerplate because Haskell doesn't have a type-level lambda. You can do this though:

newtype Comp f g a = Comp { unComp :: f (g a) }

Now you can write:

type ListList = Comp [] []

And write functions using it:

f :: ListList Int -> ListList Int
f = Comp . map (map (+1)) . unComp

Functor composition like this has applications in several areas, notably Swierstra's "Data types a la carte"

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