【问题标题】:What does forall on the right of a function arrow mean?函数箭头右侧的 forall 是什么意思?
【发布时间】:2013-10-10 10:04:28
【问题描述】:

Section 7.12.5 of the GHC Users Guide 的主题是高阶多态性。除其他外,还有一些示例有效类型:

f4 :: Int -> (forall a.a->a)

现在我想知道这种类型是什么意思。我认为它与以下内容相同:

f4' :: forall a. Int -> a -> a

如果是这样,我们一般是否可以像上面那样(出现在最右边箭头的右侧)在心理上将 forall 移动到左侧,假设在其余部分中没有出现同名的类型变量类型(但这可以简单地处理重命名)?

例如,以下仍然是正确的,不是吗:

f5 :: Int -> (forall a. (forall b. b -> a) -> a)
f5' :: forall a. Int -> (forall b. b -> a) -> a

非常感谢您提供有见地的答案。

背景:在这个talk about lenses by SPJ,我们有:

type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s

然后,当您构图时,结果中就有这样的镜头类型。 因此,我只是想知道我的直觉是否正确,结果中的 forall 并不重要 - 由于类型同义词,它只是“意外地”出现。否则,我想了解的上述f4,f4'和f5,f5'的类型之间肯定存在一些差异。

这是一个 ghci 会话:

Prelude> let f5 :: Int -> (forall a. (forall b. b -> a) -> a); f5 i f = f i
Prelude> :t f5
f5 :: Int -> (forall b. b -> a) -> a
Prelude> 

看起来 GHC 同意我的观点,至少在这种情况下......

【问题讨论】:

    标签: haskell ghc


    【解决方案1】:

    您的示例中的f4 可以被普遍量化,因为Int -> (forall a. a -> a)forall a. Int -> (a -> a) 基本相同。

    但是我们不能将你类比应用于这个 Rank2 类型(forall a. a -> a) -> (forall b. b -> b)。此类型与forall b. (forall a. a -> a) -> (b -> b) 基本相同。但是将第一个 forall 移出 (forall a b. (a -> a) -> (b -> b)) 从本质上改变了类型的语义。

    f :: (forall a. a -> a) -> (forall b. b -> b) -- Rank 2
    g :: forall a b. (a -> a) -> (b -> b)         -- Rank 1
    

    要查看差异,您可以将g 中的a 实例化为Int,从而可以将Int -> Int 类型的函数传递给g。另一方面,f 的参数必须是普遍量化的(由函数类型之前的 forall 指定)并且应该适用于所有类型(此类函数的示例是 id)。

    Here 很好地解释了更高等级的类型。

    【讨论】:

    • 感谢您的详细说明。我看到我关于左移的问题可能会被误解。我的意思是,当然,只有出现在最右边的顶级箭头右侧的 foralls。
    • @Ingo 这不是一个正确的类比,但如果返回类型为 Rank1,我认为没有问题。
    • 我希望我知道你所说的“正确的类比”和“基本相等”的确切含义。我猜,这个“本质上”是我问题的关键。如果我们不能直截了当地说:他们是平等的,那么差异在哪里?
    • 在我的示例 f5 与 f5' 中就是这样。区别在哪里?
    • GHCi 似乎以我为 f5' 提供的形式打印 f5 的类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 2017-08-26
    • 1970-01-01
    • 2015-05-15
    相关资源
    最近更新 更多