Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell &引用;Eta减少“;不总是在哈斯克尔举行吗?_Haskell_Higher Rank Types - Fatal编程技术网

Haskell &引用;Eta减少“;不总是在哈斯克尔举行吗?

Haskell &引用;Eta减少“;不总是在哈斯克尔举行吗?,haskell,higher-rank-types,Haskell,Higher Rank Types,我发现我可以说 {-# LANGUAGE RankNTypes #-} f1 :: (forall b.b -> b) -> (forall c.c -> c) f1 f = id f (我不能告诉我我可以在这里做“减少Eta”),但是 未能编译: Couldn't match expected type `c -> c' with actual type `forall b. b -> b' Expected type: (forall

我发现我可以说

{-# LANGUAGE RankNTypes #-}
f1 :: (forall b.b -> b) -> (forall c.c -> c)
f1 f = id f
(我不能告诉我我可以在这里做“减少Eta”),但是

未能编译:

Couldn't match expected type `c -> c'
            with actual type `forall b. b -> b'
Expected type: (forall b. b -> b) -> c -> c
  Actual type: (forall b. b -> b) -> forall b. b -> b
In the expression: id
In an equation for `f2': f2 = id
事实上,在更复杂的情况下,我也有类似的问题,但这是我能想到的最简单的例子。因此,要么HLint无法在此处提供适当的建议,要么编译器将检测到这种情况,是吗

更新

看起来很像。然而,尽管两个答案都很有用,但都不能让我满意,因为它们似乎没有触及问题的核心

例如,我甚至不允许使用建议的秩2类型分配
id

f2 :: (forall b.b -> b) -> (forall c.c -> c)
f2 = id :: (forall b.b -> b) -> (forall c.c -> c)
如果问题只是关于类型推断,那么显式类型表示法应该解决它(id有type
a->a
,并且它被限制为
(forall b.b->b)->(forall c.c->c)
。因此,为了证明这种用法的合理性,
(forall b.b->b)
必须匹配
(forall c.c->c)
,这是正确的)。但上面的例子表明情况并非如此。因此,这是“eta-reduce”的一个真正例外:您必须显式地向两侧添加参数,以将中的秩1类型化值转换为秩2类型化值


但为什么会有这样的限制呢?为什么计算机不能自动统一秩1类型和秩2类型(忘记类型推断,所有类型都可以用符号表示)?

我不确定HLint是否知道秩1类型和秩2类型,也许不知道

事实上,随着时间的延长,eta的降低通常是不可能的。GHC不能仅仅统一
a->a
(forall b.b->b)->(forall c.c->c)
,否则它将完全破坏Rank1-code1的类型推断能力。哦,用
a
参数统一
(对于所有b.b->b)
不是问题;结果被确认为
(对于所有b.b->b)
,与
(对于所有c.c->c)
匹配


1考虑者
地图id[(+1),(*2)]
。如果
id
被允许具有您正在处理的类型,编译器可能最终为多态
Num
函数生成不同的实例选择,这当然是不可能的。还是应该?我不确定,想想看


无论如何,我很确定,它证明了使用RankNTypes,完全类型推断是不可能的,因此,至少在Rank1子集中,GHC必须默认这是一个不太可能的多态选择。

EclipseFP可以帮助我为顶级函数添加类型签名,这些类型签名通常使用
RankNTypes
,但我不确定它们是否来自HLint。据我所知,GHC根本无法推断出更高阶的类型,但它返回其类型推断警告的格式是无效的语法,没有明确的foralls,这是RankNTypes暗示的,这是GHC在拒绝解析foralls时通常建议的扩展。我相信这是正确的(几乎)不可能在秩-2多态lambda演算中推断类型(我不确定还有什么其他特性可以接受).但它显然是毛茸茸的,没有进入更高的级别,可能与其他各种现代Haskell功能冲突。可能是Emm的复制品…另一个有趣的问题。好吧。但我必须说,这个问题基本上是两个问题的结合:帖子中的问题是关于eta降低,你的问题是关于类型专业化,以及我的两个都很好。
f2 :: (forall b.b -> b) -> (forall c.c -> c)
f2 = id :: (forall b.b -> b) -> (forall c.c -> c)