Haskell 在给定应用f时无法推断(应用f0)

Haskell 在给定应用f时无法推断(应用f0),haskell,Haskell,我很难理解为什么下面的代码中有两个独立的f和f0应用约束(需要减缩器包) 我想我需要告诉大家我想要f0~f,其中f0是通过使用pure独立推断出来的 我试图简化: u :: (Applicative f, Monoid m) => e -> Ap f m u = undefined m :: (Applicative f) => Ap f (Max Int) m = u $ (pure (2 :: Int)) 一旦e更改为f e,它将编译,以便上下文可以“统一”。但我不知

我很难理解为什么下面的代码中有两个独立的
f
f0
应用约束(需要
减缩器
包)

我想我需要告诉大家我想要
f0~f
,其中
f0
是通过使用
pure
独立推断出来的

我试图简化:

u :: (Applicative f, Monoid m) => e -> Ap f m
u = undefined 

m :: (Applicative f) => Ap f (Max Int)
m = u $ (pure (2 :: Int))
一旦
e
更改为
f e
,它将编译,以便上下文可以“统一”。但我不知道如何统一上下文


我的目标是使用应用半群进行foldReduce(如果可能的话)因此,
length
将被有效版本取代。

标准解决方案是使用
ScopedTypeVariables
来宣布
apm
签名中的
f
pure
生成的
f
是相同的
f
。因此:

{-# LANGUAGE ScopedTypeVariables #-}
import Data.Semigroup.Applicative
import Data.Semigroup.Reducer
import Data.Semigroup

apm :: forall f. Applicative f => Ap f (Max Int)
apm = unit (pure 2 :: f Int)

不要丢失所有的
;扩展的一个要求是将
f
纳入定义主体的范围。

这是因为省略
forall
将隐含地将其放置为
apm::Applicative f=>forall f。Ap f(Max Int)
?@SimonShine不,没有这样合理的理由。它只是一个任意的规则集,用来区分与该声明相关联的定义中应该绑定的变量和不应该绑定的变量。许多人甚至认为规则是反向的(默认情况下,变量应该是有约束的,如果它们被显式地普遍量化,则不受约束);现有规则被选择为与之相反,只是为了打开扩展不会改变任何现有代码的含义,而不是出于任何深刻的理论原因。
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Semigroup.Applicative
import Data.Semigroup.Reducer
import Data.Semigroup

apm :: forall f. Applicative f => Ap f (Max Int)
apm = unit (pure 2 :: f Int)