首页 > 解决方案 > fmap (+3) (*3) 不应该等同于 \x -> ((x+3)*3) 吗?

问题描述

Learn you a Haskell中,给出了

fmap (+3) (*3)

相当于

\x -> ((x*3)+3))

但是,我不明白为什么。不应该是\x -> ((x+3)*3)吗?

我不知道fmapfor (*3)functor 的实现,但是我的直觉告诉我,由于 functor(*3)等价于\x -> x * 3,所以 map(+3)会先应用,然后(*3)再应用,但反之亦然。我在这里缺少什么?

标签: haskellfunctor

解决方案


fmap必须遵守两条规律:

  1. fmap id == id
  2. fmap (f . g) == fmap f . fmap g

您提出的定义fmap' f g == g . f满足第一定律但违反第二定律:

fmap' id f == f . id == f == id f  -- OK

fmap' (f . g) h == h . (f . g)
                == (h . f) . g
                == (fmap' f h) . g
                == fmap' g (fmap' f h)
                == (fmap' g . fmap' f) h  -- violation, since (.) is not commutative

正确的定义,fmap f g = f . h,同时满足:

fmap id f == id . f == f == id f

fmap (f . g) h == (f . g) . h
               == f . (g . h)
               == fmap f (g . h)
               == fmap f (fmap g h)
               == (fmap f . fmap g) h

推荐阅读