Haskell Learning-functor

Source: Internet
Author: User

Source Address: Haskell Learning-functor

What is functor

functor is an object that can perform map operations, and functor is like an expression with a semantic appended to it, which can be likened to a box. The definition of functor can be interpreted like this: given a mapping of A to B function and a box, the result will return to the box loaded with B. Fmap can be thought of as a function that accepts functions and a functor , which apply function to each element of the functor (mapping).

-- Functor的定义class Functor f where    fmap :: (a -> b) -> f a -> f b

For a type to be able to map operations (map over), it must inherit the functor base class and implement the Fmap function within it. Let's look at some of the default functor patterns:

    1. List of lists, very well understood, operation list we generally use the map function, which is actually fmap for a specific instance of the list, they are equivalent in the list.

      -- 作为functor 的定义:instance Functor [] where    fmap = map-- 实例fmap (*2) [1,2,3]> [2,4,6]
    2. maybe, which is a widely used data type in Haskell, has a Just value and nothing in two cases, respectively, to indicate success and failure.

      -- Maybe 的 functor 定义:instance Functor Maybe where    fmap f (Just x) = Just (f x)    fmap f Nothing = Nothing-- 实例fmap (*2) (Just 1)> Just 2fmap (*2) (Nothing)> Nothing
    3. IO, input and output, such as reading keyboard input, printing strings, etc.

      -- IO 的 Functor 定义instance Functor IO where    fmap f action = do          result <- action          return (f result)-- 实例fmap ("hello! "++) getLinejeff -- 输入名字,打印时添加“hello”> "hello! jeff"
Functor (-) R morphology

R actually represents a function combination, which is equivalent to (.)

-- 下面两个定义是等价的,也就是 (->) r 形式下的 Functor 其实等价于 结合律instance Functor ((->) r) where    fmap f g = (\x -> f (g x))instance Functor ((->) r) where    fmap = (.)-- 实例fmap (*3) (+100) 1> 303(*3) . (+100)  $ 1> 303
Functor Law

If a type follows these two laws, it has the same nature as the other functor for mapping.

    1. FMAP id = ID
      If we do a map ID for functor, the new functor should be the same as the original one.

      fmap id (Just 3) > Just 3id (Just 3) > Just 3
    2. Fmap (f. g) = Fmap F. Fmap g , which is functor , can be applied to a function combination.

Applicative Functor

Why do I need applicative Functor, and under what circumstances use it. From the functor definition we know that the FMAP function can only map a single box, but suppose you need to map two three, or even more, of a box? Or do you want to handle the box where the return value is a function? And that's what applicative Functor to deal with.
  applicative Functor can be seen as an added version of Functor, which, from the definition, mainly includes pure and <*> two functions.

-- Applicative Functor 定义class (Functor f) => Applicative f where    pure :: a -> f a    (<*>) :: f (a -> b) -> f a -> f b
  • Pure:: A-f a means to place the normal value under the default context (semantics). For example, if it is a list, then it represents [] , if it is maybe, then it is Just value/nothing.
  • (<*>) accept a functor with a function with another functor, very similar to Fmap, which is like the enhanced version of Fmap. Use the applicative functors in a applicative style way. Like pure f <*> x <*> y <*> ... This function can eat any number of parameters.

    -- 与fmap类型的对比,可以看出函数 a -> b 被装进了盒子 f 中(<*>) :: f (a -> b) -> f a -> f bfmap :: (a -> b) -> f a -> f b-- <*> 是左结合的,因此以下两个表达式是相等的pure (+) <*> Just 3 <*> Just 5 (pure (+) <*> Just 3) <*> Just 5。
  • (<$>) is another very common symbol in applicative functor , which is in fact the infix version of the Fmap. Because the combination of Fmap write applicative functor more convenient.

    (<$>) :: (Functor f) => (a -> b) -> f a -> f bf <$> x = fmap f x-- 用<*>实现相同的功能pure f <*> x = fmap f x

Then take a look at a few default applicative functor, inherited applicative, must implement the pure and (<*>) function

  1. Maybe type

    -- Maybe 的 Applicative 定义:instance Applicative Maybe where    pure = Just    Nothing <*> _ = Nothing    (Just f) <*> something = fmap f something-- 实例pure (+3) <*> Just 9> Just 12pure (+) <*> Just 3 <*> Just 5> Just 8
  2. The
  3. list is also a applicative functor, as you can see from the definition of the applicative style that uses list to fully implement the list Comprehension the function of the . So applicative style is a good way to replace certain types of list comprehension for lists.

     --Definition of List instance applicative [] where pure x = [x] fs <*> xs = [F x | F <  -FS, x <-xs]--instances [(+3), (* *)] <*> [1,2]> [4,5,2,4]--The following expressions have the same functionality (*) <$> [2,5,10] <*> [8,10,11]-- Applicative style[x * y | x <-[2,5,10], y <-[8,10,11]]--list comprehension> [16,20,22,40,50,55,80,100,110]< /code> 
  4. io , an example of the following IO, can think of getLine as a box to get strings in the real world, and applicative functor expression creates a larger box that will send two boxes to the terminal to fetch the strings, And the results are strung together and put into their own boxes.

    --IO 的 Applicative instanceinstance Applicative IO where    pure = return    a <*> b = do        f <- a        x <- b        return (f x)-- 实例 将输入的两个字符串合并(++) <$> getLine <*> getLineaabb> "aabb"
Applicative Functor (-) R morphology

(-) R pattern definition

instance Applicative ((->) r) where    pure x = (\_ -> x)    f <*> g = \x -> f x (g x)
    • When you wrap a value into applicative functor with pure, the result will always be that value.
    • Feeding the two applicative functor to <*> can produce a new applicative functor

Then use the above knowledge synthetically, and take a look at several ways to actually apply applicative. More powerful and flexible than functor,applicative functor.

-- 左结合形式, 第一项必须为含有函数的functor,右边全部为functorpure (\x y z -> x+ y +z) <*> Just 3 <*> Just 4 <*> Just 5> Just 12[(+3),(*2)] <*> [1,2]> [4,5,2,4]-- fmap(<$>) 形式,第一项为普通函数,右边都为functor(+) <$> Just 1 <*> Just 2> Just 3(\x y z -> x + y +z) <$> [1,2] <*> [2,3] <*> [4,5]> [7,8,8,9,8,9,9,10]-- (<$>) (->) r 形式,全部为普通函数,用单个参数调用执行(\x y z -> [x,y,z]) <$> (3+) <*> (*100) <*> (`div`2) $ 2> [5,200,1]
Applicative Functor Auxiliary function
  1. LiftA2
    It's just a applicative function, and of course there are 3 versions of liftA3, and LiftA is equivalent to fmap

    -- 与applicative 的等价形式liftA2 f a b = f <$> a <*> b-- 以下表达式功能一致liftA2 (:) (Just 3) (Just [4])(:) <$> Just 3 <*> Just [4]pure (:) <*> Just 3 <*> Just [4]> Just [3,4]
  2. sequencea
    When applied to a function, sequencea accepts a list containing a bunch of functions and callbacks a function that lists the callbacks. Sequencea is very useful when we have a string of functions that want to feed the same input to them and see the results.
    when used on an I/O action, sequencea is equivalent to sequence . He accepts a string of I/O action and callbacks an I/O action, which computes every I/O action in the list and places the result in a list

     

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.