Haskell 追溯函数部分应用的类型

Haskell 追溯函数部分应用的类型,haskell,haskell-lens,partial-application,Haskell,Haskell Lens,Partial Application,我一直在检查镜头的类型以了解它,但很难找出由此产生的部分应用类型 初始类型如下:type RefF a b=forall f。函子f=>(b->f b)->(a->f a) 应用于Identityfunctor的上述类型如下所示: (b -> Identity b) -> (a -> Identity a) modify :: RefF a b -> (b -> b) -> a -> a modify r m = runIdentity . r (Id

我一直在检查
镜头的类型
以了解它,但很难找出由此产生的部分应用类型

初始类型如下:
type RefF a b=forall f。函子f=>(b->f b)->(a->f a)

应用于
Identity
functor的上述类型如下所示:

(b -> Identity b) -> (a -> Identity a)
modify :: RefF a b -> (b -> b) -> a -> a
modify r m = runIdentity . r (Identity . m)
其修改功能定义如下:

(b -> Identity b) -> (a -> Identity a)
modify :: RefF a b -> (b -> b) -> a -> a
modify r m = runIdentity . r (Identity . m)
我对上述定义进行了单独分解,以便更好地理解它

从上面看,
标识的类型。m
b->标识b

我甚至用typechecker验证了这一点:

check1 :: (b -> b) -> b -> Identity b
check1 m = Identity . m
现在,我尝试表述
r(Identity.m)
的类型。这就是我的思想变得空虚的地方。部分应用
r(Identity.m)
的实际结果似乎是
a->Identity a
,如下所示:

check2 :: RefF a b -> (b -> Identity b) -> a -> Identity a
check2 r che = r che
一个人如何从心理上理解这一点?当我尝试将
che
部分应用于
r
时,它似乎不适合:

The type of `r` is   : (b -> Identity b) -> (a -> Identity a)
The type of `che` is : (b -> Identity b)
我们如何找出
r che
的部分应用是
(a->Identity a)

当我尝试将che部分应用于r时,它似乎不适合:

The type of `r` is   : (b -> Identity b) -> (a -> Identity a)
The type of `che` is : (b -> Identity b)
r
具有类型

(b -> Identity b) -> (a -> Identity a)
(b -> Identity b)
这意味着它的第一个参数需要有类型
(b->Identity b)

che
具有类型

(b -> Identity b) -> (a -> Identity a)
(b -> Identity b)
正如所需的
r
,因此
r che
将工作并具有类型
(a->Identity a)

在应用到第三个参数之后,假设它被命名为
arg
,属于
modify
,这个
arg
具有类型
a
r(Identity.m)arg
将具有类型
标识a
,在其上应用
runIdentity
后,结果将具有类型
a


您可以这样推断
修改rm
的类型:

(b -> Identity b) -> (a -> Identity a)
modify :: RefF a b -> (b -> b) -> a -> a
modify r m = runIdentity . r (Identity . m)
  • r
    具有类型
    RefF a b
    ,即
    (b->f b)->(a->f a)
  • m
    具有类型
    b->b
  • Identity
    具有所有a的类型
    。a->Identity a
    ,因此
    Identity。m
    具有类型
    b->标识b
  • r(Identity.m)
    具有类型
    a->Identity a
    ,因为
    f
    必须是
    Identity
  • runIdentity
    具有所有a的类型
    。标识a->a
    ,因此
    运行标识。r(Identity.m)
    具有类型
    a->a

  • 我不知道我是否理解这个问题,一切看起来都很好
    che
    r
    的第一个输入参数类型统一,因此
    r che
    工作对不起,我的坏消息。我现在明白了。