haskell - (fmap . fmap) 如何进行类型检查

标签 haskell functor

我浏览了一篇文章( http://comonad.com/reader/2012/abstracting-with-applicatives/ )并在那里找到了以下代码片段:

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

(fmap . fmap) 实际上如何进行类型检查?

它们的类型是:

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

现在从这里我根本看不到 fmap . fmap 会进行类型检查吗?

最佳答案

首先让我们将类型变量的名称更改为唯一:

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

现在 . 的第一个参数的类型为 a -> b,我们提供一个类型为 (c -> d) -> (f c -> f d),因此 ac -> dbf c -> f d 。到目前为止我们已经:

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

. 的第二个参数具有类型 r -> a 又名 r -> (c -> d) 以及我们给出的参数具有类型 (x -> y) -> (g x -> g y),因此 r 变为 x -> y, c 变为 g xd 变为 g y。所以现在我们有:

(.)       :: (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)

关于haskell - (fmap . fmap) 如何进行类型检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23030638/

相关文章:

haskell - 如果类型构造函数具有多个类型参数,如何使类型构造函数成为 Functor 类型类的一部分?

f# - 你能向我解释一下 OCaml 仿函数吗?

haskell - Haskell 中类型之间的转换

haskell - 具有重载数字和字符串文字的类型类多态性

haskell - Plutus Playground 中的 Plutus 解释器错误

list - 列表模式中函数定义的顺序是否重要

c++ - 使用容器中的第 n_th 个元素,但使用另一个键

haskell - 如何使用stack镜像容器?

C++定义虚基类重载运算符

c++ - 将一个仿函数的实例传递给另一个仿函数