Functional programming-Re-understanding generics (2)

Source: Internet
Author: User

Recalling the previous section, in order to enrich the modeling type, the programming language introduced generics, such as optional<t>,result<t>. We call generics also the type promotion (lifting), the problem is that the previous function can no longer adapt to the type of ascension, imagine that there is already a a->b function, but at this time you have a e<a> variable, you can not directly pass e<a> to a A In the >b function. As mentioned in the previous section, once your type has been promoted (lifting), you should be able to keep him in a state of ascension rather than switching back and forth in the ascending type (e<a>) and a directly.

To achieve this, mathematicians have discovered some rules that can be achieved through a number of functions. For example: When you already have a defined function a->b, and this time there is a promoted type E<a>, at this point, you can use the Map/select function to directly e<a> the A->B application on the.

In a sense, the Map/select function has the function of lifting functions. The reason why a->b can function on e<a> is because the Map/select function promotes the function a->b to e<a->b>. Because of this, some languages also call the map function the lift function.

return function

Before we go any further, let's look at another function return , some of which are also called pure/unit/point .

returnThe function is to promote normal type A to e<a>. For example, the following C # code:

var x = Optional.Some(10); //将int提升为Optional<int>var y = Optional.None<int>; //将int提升为Optional<int>var z = new List<int>(){1,2,3}; //将int提升为List<int>

In general, you don't need to define a return function individually, but when we talk about return a function you should know his intentions.

Promoting functions with the map function

In addition return to functions that promote types, the map function also has the effect of ascending types.
Consider the following scenario:

let add1 x = x + 1let result = Some 2 |> Option.map add1

Given a function add1:a->b, then the ADD1 is promoted to e< (A->b) by Option.map, and the some 2 is passed, and the result some 3 is obtained.
The above function Add1 has only one parameter, what happens if you map a function that has two parameters?

let add x y = x + ylet result' = Some 2 |> Option.map add

Because add accepts two parameters x and Y, and the first parameter is lifted by the map and passed to some 2, the resulting result ' is a lift function option< (a->b) >. C # does not support this approach, and the Select method in C # accepts only Func<tsource, Tresult>, which means that the Select method in C # accepts only one parameter of the function. You cannot promote a function with multiple parameters by using SELECT.
In the same vein, you promote a function with 3 parameters via map:

let add x y z = x + y + zlet result' = Some 2 |> Option.map add

The resulting result ' is option< (a->b->c) >.

Apply function

For the normal type of function a->b->c, you can pass in A and B through the partial application, and finally get C.

//定义一个函数 add: a -> b -> clet add a b =    a + b    let add10 = add 10  // add10: b -> clet result = add10 2 // result: 12

We already know that there are two ways to lift functions: return and map, then:
If you have a option< (a->b->c) > function, can you do partial application in the world of ascending type?

// 通过return 函数创建一个提升函数Option<(a->b->c)>let add' = Some (fun x y -> x + y) // 试图在add'函数上传入Some 2做partial applicationlet add2' = add' (Some 2)

The above function will fail to compile, which means that the partial application cannot be done for a lift function. If we can define a function, he can accept a function of ascending type and a parameter of ascending type, at the same time get the result of another ascending type, then our aim is achieved:

The following is the option<t> type of apply definition:

module Option =    let apply fOpt xOpt =         match fOpt,xOpt with        | Some f, Some x -> Some (f x)        | _ -> None

With the Apply function, you can apply a partial application to a function that promotes a type:

let add' = Some (fun x y -> x + y) let add2' = Some 2 |> Option.apply add'let add23' = Some 3 |> Option.apply add'2
Infix expression

Functions in F # or C # are prefix expressions, such as an add function that accepts two parameters:

let add x y = x + ylet result = add x y // 函数名在前面,两个参数在后面

But the operators in mathematics are usually infix expressions, such as the plus operator in math:

let result = 1 + 2

The plus sign is written in the middle, and two parameters are written on both sides. In the same way, any function with two parameters can be made into infix expressions by defining an operator, for example, in F # by defining an operator in the following way:

let (<*>) = Option.apply

With operator <*>, the apply process above can be written like this:

(Some add) <*> (Some 2) <*> (Some 3)

The above code uses the return function to lift the function, and we know that the map function can also raise the function:

let (<!>) = Option.maplet (<*>) = Option.applyadd <!> (Some 2) <*> (Some 3)

Like Functor laws, there are also four so-called "applicative laws", these four laws I will not describe each, from the point of view of the code, this article describes the Apply function is called applicative Functor.

MAP2 and MAP3 functions

For the above instance, the ability to elevate a function with two parameters and accept two ascending types, F # defines a function called MAP2:

let result = Option.map2 add (Some 2) (Some 3)

Similarly, if it is a function of 3 parameters, it can be done by the MAP3 function.

What type of support Map/apply/return?

Almost all of the generics you can use can support these three functions, and if you write your own generic type, try adding these three functions.

What's the use of applicative and apply?

If you see here you already understand what is applicative, but in the end what kind of scene can use applicative? What is the use of actual software engineering? Later articles will describe the specific usage, please keep your eye on it.

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.