本文介绍了如何(fmap。fmap)typechecks的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读一篇文章(),并在其中找到以下代码片段:

  newtype撰写fga = Compose(f(ga))导出显示

实例(Functor f,Functor g)=> Functor(Compose fg)其中
fmap f(Compose x)= Compose $(fmap。fmap)fx

实际上(fmap。fmap) typechecks?



它们的类型是:

 (。)::(a  - > b) - > (r→a)→> (r  - > b)
fmap ::(a - > b) - > f a - > f b
fmap ::(a - > b) - > f a - > f b

现在我从这里看不出 fmap。首先让我们将类型变量的名称更改为唯一:

 (。)::(a  - > b) - > (r→a)→> (r  - > b)
fmap :: Functor f => (c - > d) - > f c - > f d
fmap :: Functor g => (x - > y) - > g x - > gy

现在第一个参数。键入 a - > b ,我们提供一个类型为(c - > d) - >的参数。 (f c - > f d),所以 a 是 c - > d 和 b 是 f c - > f d 。所以到目前为止,我们有:

 (。):: Functor f => - 左操作数
((c - > d) - >(f c - > f d)) - >
- 右操作数
(r - >(c - > d)) - >
- 结果
(r - >(fc - > fd))

第二个参数。的类型为 r - > a a.k.a. r - > (c - > d)并且我们给出的参数具有类型(x - > y) - > (g x - > g y),所以 r 变成 x - > y , c 变成 gx 和 d 变成 gy 。所以现在我们有:

 (。)::(Functor f,Functor g)=> - 左操作数
((g x - > g y) - >(f(g x) - > f(g y))) - >
- 右操作数
((x - > y) - >(g x - > g y)) - >
- 结果
(x - > y) - > f(g x) - > f(g y)
fmap.fmap ::(Functor f,Functor g)=> (x - > y) - > f(g x) - > f(g y)


I have been going through a article(http://comonad.com/reader/2012/abstracting-with-applicatives/) and found the following snippet of code there:

newtype Compose f g a = Compose (f (g a)) deriving Show

instance (Functor f, Functor g) => Functor (Compose f g) where
    fmap f (Compose x) = Compose $ (fmap . fmap) f x

How does actually (fmap . fmap) typechecks ?

Their types being:

(.)  :: (a -> b) -> (r -> a) -> (r -> b)
fmap :: (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b

Now from here I can see in no way in which fmap . fmap will typecheck ?

解决方案

First let's change the type variables' names to be unique:

(.)  :: (a -> b) -> (r -> a) -> (r -> b)
fmap :: Functor f => (c -> d) -> f c -> f d
fmap :: Functor g => (x -> y) -> g x -> g y

Now the first parameter to . has type a -> b and we supply an argument of type (c -> d) -> (f c -> f d), so a is c -> d and b is f c -> f d. So so far we have:

(.) :: Functor f => -- Left operand
                    ((c -> d) -> (f c -> f d)) ->
                    -- Right operand
                    (r -> (c -> d)) ->
                    -- Result
                    (r -> (f c -> f d))

The second parameter to . has type r -> a a.k.a. r -> (c -> d) and the argument we give has type (x -> y) -> (g x -> g y), so r becomes x -> y, c becomes g x and d becomes g y. So now we have:

(.)       :: (Functor f, Functor g) => -- Left operand
                                       ((g x -> g y) -> (f (g x) -> f (g y))) -> 
                                       -- Right operand
                                       ((x -> y) -> (g x -> g y)) ->
                                       -- Result
                                       (x -> y) -> f (g x) -> f (g y)
fmap.fmap :: (Functor f, Functor g) => (x -> y) -> f (g x) -> f (g y)

这篇关于如何(fmap。fmap)typechecks的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 07:00