- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我不太熟悉forall
,但最近读到了这个问题:What does the `forall` keyword in Haskell/GHC do?
其中一个答案是这个例子:
{-# LANGUAGE RankNTypes #-}
liftTup :: (forall x. x -> f x) -> (a, b) -> (f a, f b)
liftTup liftFunc (t, v) = (liftFunc t, liftFunc v)
解释很好,我明白 forall
在这里做什么。但我想知道,是否有特殊原因导致这不是默认行为。是否有过不利的时候?
编辑:我的意思是,默认情况下无法插入 forall 是否有原因?
最佳答案
嗯,它不是 Haskell 2010 标准的一部分,因此默认情况下不会启用它,而是作为语言扩展提供。至于为什么它不在标准中,n 级类型比 Haskell 标准的普通 1 级类型更难实现;它们也并不那么频繁地被需要,因此出于语言和实现简单性的原因,委员会可能决定不打扰它们。
当然,这并不意味着 n 级类型没有用处;它们确实如此,没有它们,我们就不会有像 ST
monad 这样有值(value)的工具。 (它提供了高效的本地可变状态 - 就像 IO
一样,您所能做的就是使用 IORef
)。但它们确实给语言增加了相当多的复杂性,并且在应用看似良性的代码转换时可能会导致奇怪的行为。例如,一些 n 级类型检查器将允许 runST (do { ... })
但拒绝 runST $ do { ... }
,即使这两个表达式在没有 n 阶类型的情况下总是等价的。请参阅this SO question有关它可能导致的意外(有时甚至是烦人)行为的示例。
如果像 sepp2k 所问的那样,您反而会问为什么必须将 forall
显式添加到类型签名中以获得更高的通用性,那么问题就在于 (forall x.x -> f x) -> (a, b) -> (f a, f b)
实际上是比 (x -> f x) -> (a, b) -> (f a, f b) 限制性更强的类型)
。对于后者,您可以传入 x -> f x
形式的任何函数(对于任何 f
和 x
),但对于前者,您传入的函数必须适用于all x
。因此,例如,String -> IO String
类型的函数将是第二个函数的允许参数,但不是第一个函数;它必须具有 a -> IO a
类型。如果后者自动转化为前者,那就太困惑了!他们是两种截然不同的类型。
将隐式的 forall
显式化可能更有意义:
forall f x a b. (x -> f x) -> (a, b) -> (f a, f b)
forall f a b. (forall x. x -> f x) -> (a, b) -> (f a, f b)
关于haskell - 为什么默认情况下 forall(RankNTypes 用法)不适用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10129101/
我试图通过给数字一个这样的类型来研究 Haskell 中的教堂数字,想法是自然数 n基本上是将以下类型的函数应用于类型 t 的值的表达式为 n次。 type Nat = forall t. (t ->
不明白为什么会这样,引用:What is the purpose of Rank2Types? -> @dfeuer 解释: ... Requiring an argument to be polym
当我使用 RankNTypes 时,似乎 (.) 运算符不能正常工作。这个限制记录在哪里? {-# LANGUAGE RankNTypes, ImpredicativeTypes #-} f :: I
下面的函数不进行类型检查。 test1 :: forall x. (Show x => x) -> String test1 = show 这是因为最后一个->无权访问该约束。 (这可能不是正确的术语
使用RankNTypes,我定义了一个不依赖于类型变量的类型。这是解决下面案例的正确方法吗? 我需要定义一些在 ST 中使用的函数,当然,这些函数不依赖于 s。然而,这会导致一个问题,即应用了两个 I
这个问题在这里已经有了答案: Understanding a rank 2 type alias with a class constraint (2 个答案) 关闭 6 年前。 我正在尝试了解类型
这编译得很好: type List a = [a] 但是当我引入类约束时,编译器要求 RankNTypes被包括: type List2 a = Num a => [a] 包含该扩展后,它编译得很好。
使用来自 here 的 rankN : {-# LANGUAGE RankNTypes #-} rankN :: (forall n. Num n => n -> n) -> (Int, Double
在游戏期间 objective包,我注意到以下类型具有有趣的属性。 > {-# LANGUAGE RankNTypes #-} > data N f r = N { unN :: forall x.
f1 和有什么区别和 f2 ? $ ghci -XRankNTypes -XPolyKinds Prelude> let f1 = undefined :: (forall a m. m
这些有什么区别? {-# LANGUAGE RankNTypes #-} f :: forall a. a -> Int f _ = 1 g :: (forall a. a) -> Int g _ =
由于类型变量不能容纳多类型,似乎使用 Rank*Types 我们不能重用现有函数,因为它们的单型限制。 例如,当中间类型是多类型时,我们不能使用函数 (.)。我们被迫在现场重新实现(.)。这对于 (.
我正在尝试在 Haskell 中尝试 System-F 类型,并通过 type 实现自然数的 Church 编码。 加载此代码时 {-# OPTIONS_GHC -Wall #-} {-# LANGU
我刚刚探索了 Rank2Types 和 RankNTypes,试图熟悉它们。但我不明白为什么以下不起作用。 g :: (forall a. forall b. a -> b) -> x -> y ->
如果我想声明一个 newtype ,使得值的类型类型被限制为具有类型类的实例,似乎我可以这样做: {-# LANGUAGE RankNTypes #-} newtype ShowBox = ShowB
import Data.ConfigFile data Test = Test { field1 :: Int , field2 :: Bool , field3 :: String
这个问题在这里已经有了答案: runST and function composition (3 个回答) 6年前关闭。 我对以下程序感到困惑。 {-# LANGUAGE RankNTypes #-}
我在几个地方读到声称可以使用 ExistentialQuantification 获得与 RankNTypes 等效的功能。有人可以举例说明为什么这是可能的或不可能的吗? 最佳答案 通常,Haskel
我明白了forall使我们能够编写多态函数。 据此chapter ,我们一般写的正规函数都是Rank 1类型。这个函数属于 Rank 2 类型: foo :: (forall a. a -> a) -
在研究 GHC 扩展时,我遇到了 RankNTypes at the School of Haskell ,其中有以下示例: main = print $ rankN (+1) rankN :: (f
我是一名优秀的程序员,十分优秀!