haskell - 什么是 Levity 多态性

标签 haskell

正如问题标题所示,我想知道什么是 Levity 多态性以及它的动机是什么?我知道this page其中有一些细节,但其中的大部分解释都超出了我的理解范围。 :)

同时this page有点友好,我仍然无法理解其背后的动机。

最佳答案

注意:此答案基于对 Levity 讨论的最新观察。有关 Levity 多态性的所有内容目前仅在 GHC 8.0 候选版本中实现,因此可能会发生变化(例如,请参阅 #11471)。

<小时/>

TL;DR:这是一种使函数在提升和未提升类型上实现多态的方法,这对于常规函数来说是不可能的。例如,以下代码不会使用常规多态性进行类型检查,因为 Int# 具有类型 #,但 id 中的类型变量具有类型*:

{-# LANGUAGE MagicHash #-}

import GHC.Prim

example :: Int# -> Int# 
example = id            -- does not work, since id :: a -> a
Couldn't match kind ‘*’ with ‘#’
When matching types
  a0 :: *
  Int# :: #
Expected type: Int# -> Int#
  Actual type: a0 -> a0
In the expression: id

请注意,(->) 仍然使用了一些魔法。

<小时/>

在开始回答这个问题之前,让我们退后一步,看看最常用的函数之一,($)

($) 的类型是什么?嗯,根据 Hackage 和报告,这是

($) :: (a -> b) -> a -> b

但是,这还没有 100% 完成。这是一个方便的小谎言。问题是多态类型(如 ab)具有类型 *。然而,(库)开发人员不仅希望对 * 类型使用 ($),还希望对 # 类型使用 ($),例如

unwrapInt :: Int -> Int#

虽然Int有类型*(它可以是底部),Int#有类型#(并且根本不可能是底部)。尽管如此,以下代码类型检查:

unwrapInt $ 42

这不应该起作用。还记得($)的返回类型吗?它是多态的,多态类型具有 * 类型,而不是 #!那么为什么它有效呢?首先,它是a bug ,然后是 hack (摘自 ghc-dev 邮件列表上的 a mail by Ryan Scott):

So why is this happening?

The long answer is that prior to GHC 8.0, in the type signature ($) :: (a -> b) -> a -> b, b actually wasn't in kind *, but rather OpenKind. OpenKind is an awful hack that allows both lifted (kind *) and unlifted (kind #) types to inhabit it, which is why (unwrapInt $ 42) typechecks.

那么 GHC 8.0 中的新类型 ($) 是什么?这是

($) :: forall (w :: Levity) a (b :: TYPE w). (a -> b) -> a -> b
-- will likely change according to Richard E.

要理解它,我们必须看看Levity:

data Levity = Lifted | Unlifted

现在,我们可以认为 ($) 具有以下类型之一,因为 w 只有两种选择:

-- pseudo types
($) :: forall a (b :: TYPE   Lifted). (a -> b) -> a -> b
($) :: forall a (b :: TYPE Unlifted). (a -> b) -> a -> b

TYPE 是一个神奇的常量,它将类型 *# 重新定义为

type * = TYPE Lifted
type # = TYPE Unlifted

种类的量化is also fairly newintegration of dependent types in Haskell 的一部分.

名称“Levity 多态性” 来自这样一个事实:您现在可以在提升类型和未提升类型上编写多态函数,这是以前的多态性限制所不允许/不可能的。同时它还摆脱了 OpenKind 黑客攻击。这真的是“只是”,处理这两种类型。

顺便说一下,你并不是唯一一个有这个问题的人。偶Simon Peyton Jones said that there's a need for a Levity wiki page和 Richard E.(当前的实现者)stated that the wiki page needs an update在当前进程上。

引用文献

关于haskell - 什么是 Levity 多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35318562/

相关文章:

performance - 如何折叠惰性类型列表([IO a])?

Haskell:强制 float 有两位小数

haskell - IO monad 内部的惰性计算

haskell - Haskell 中的 GC 在软实时应用程序中暂停

Haskell 设计 : Struggling with IO

haskell - 如何使用 Monad 实现全局计数器?

haskell - 像函数一样组合类型构造函数

haskell - foldl 是否比它严格的表亲 foldl' 更可取?

haskell - 如何避免使用 snapframework 在 haskell 中的不同 'string' 类型之间进行转换?

haskell - 解决模糊类型变量