How do functors work in haskell?

前端 未结 5 2202
悲&欢浪女
悲&欢浪女 2020-11-27 10:21

I\'m trying to learn Haskell and I\'m through all the basics. But now I\'m stuck, trying to get my head around functors.

I\'ve read that \"A functor transforms one

5条回答
  •  臣服心动
    2020-11-27 10:45

    In Haskell, functors capture the notion of having containers of "stuff", such that you can manipulate that "stuff" without changing the shape of the container.

    Functors provide one function, fmap, that lets you do this, by taking a regular function and "lifting" it to a function from containers of one type of element to another:

    fmap :: Functor f => (a -> b) -> (f a -> f b) 
    

    For example, [], the list type constructor, is a functor:

    > fmap show [1, 2, 3]
    ["1","2","3"]
    

    and so are many other Haskell type constructors, like Maybe and Map Integer1:

    > fmap (+1) (Just 3)
    Just 4
    > fmap length (Data.Map.fromList [(1, "hi"), (2, "there")])
    fromList [(1,2),(2,5)]
    

    Note that fmap is not allowed to change the "shape" of the container, so if for example you fmap a list, the result has the same number of elements, and if you fmap a Just it can't become a Nothing. In formal terms, we require that fmap id = id, i.e. if you fmap the identity function, nothing changes.

    So far I've been using the term "container", but it's really a bit more general than that. For example, IO is also a functor, and what we mean by "shape" in that case is that fmap on an IO action shouldn't change the side effects. In fact, any monad is a functor2.

    In category theory, functors allow you to convert between different categories, but in Haskell we only really have one category, often called Hask. Therefore all functors in Haskell convert from Hask to Hask, so they are what we call endofunctors (functors from a category to itself).

    In their simplest form, functors are somewhat boring. There is only so much you can do with just one operation. However, once you start adding operations, you can go from regular functors to applicative functors to monads and things quickly get a lot more interesting, but that's beyond the scope of this answer.

    1 But Set is not, because it can only store Ord types. Functors must be able to contain any type.
    2 Due to historical reasons, Functor is not a superclass of Monad, though many people think it should be.

提交回复
热议问题