函数概念的讲解 自己的语言回答 通俗易懂 简洁

函数概念的讲解 自己的语言回答 通俗易懂 简洁,第1张

函数的有关概念

1.函数的概念:设A、B是非空的数集,如果按照某个确定的对应关系f,使对于集合A中的任意一个数x,在集合B中都有唯一确定的数f(x)和它对应,那么就称f:A→B为从集合A到集合B的一个函数.记作: y=f(x),x∈A.其中,x叫做自变量,x的取值范围A叫做函数的定义域;与x的值相对应的y值叫做函数值,函数值的集合{f(x)| x∈A }叫做函数的值域

注意:○2如果只给出解析式y=f(x),而没有指明它的定义域,则函数的定义域即是指能使这个式子有意义的实数的集合;○3 函数的定义域、值域要写成集合或区间的形式.

定义域补充

能使函数式有意义的实数x的集合称为函数的定义域,求函数的定义域时列不等式组的主要依据是:(1)分式的分母不等于零; (2)偶次方根的被开方数不小于零; (3)对数式的真数必须大于零;(4)指数、对数式的底必须大于零且不等于1 (5)如果函数是由一些基本函数通过四则运算结合而成的那么,它的定义域是使各部分都有意义的x的值组成的集合(6)指数为零底不可以等于零 (6)实际问题中的函数的定义域还要保证实际问题有意义

(又注意:求出不等式组的解集即为函数的定义域)

2. 构成函数的三要素:定义域、对应关系和值域

再注意:(1)构成函数三个要素是定义域、对应关系和值域.由于值域是由定义域和对应关系决定的,所以,如果两个函数的定义域和对应关系完全一致,即称这两个函数相等(或为同一函数)(2)两个函数相等当且仅当它们的定义域和对应关系完全一致,而与表示自变量和函数值的字母无关相同函数的判断方法:①表达式相同;②定义域一致 (两点必须同时具备)

(见课本21页相关例2)

值域补充

(1)、函数的值域取决于定义域和对应法则,不论采取什么方法求函数的值域都应先考虑其定义域 (2)应熟悉掌握一次函数、二次函数、指数、对数函数及各三角函数的值域,它是求解复杂函数值域的基础

3 函数图象知识归纳

(1)定义:在平面直角坐标系中,以函数 y=f(x) , (x∈A)中的x为横坐标,函数值y为纵坐标的点P(x,y)的集合C,叫做函数 y=f(x),(x ∈A)的图象.

C上每一点的坐标(x,y)均满足函数关系y=f(x),反过来,以满足y=f(x)的每一组有序实数对x、y为坐标的点(x,y),均在C上 即记为C={ P(x,y) | y= f(x) , x∈A }

图象C一般的是一条光滑的连续曲线(或直线),也可能是由与任意平行与Y轴的直线最多只有一个交点的若干条曲线或离散点组成

(2) 画法

A、描点法:根据函数解析式和定义域,求出x,y的一些对应值并列表,以(x,y)为坐标在坐标系内描出相应的点P(x, y),最后用平滑的曲线将这些点连接起来

B、图象变换法(请参考必修4三角函数)

常用变换方法有三种,即平移变换、伸缩变换和对称变换

(3)作用:

1、直观的看出函数的性质;2、利用数形结合的方法分析解题的思路提高解题的速度

发现解题中的错误

4.快去了解区间的概念

(1)区间的分类:开区间、闭区间、半开半闭区间;(2)无穷区间;(3)区间的数轴表示.

5.什么叫做映射

一般地,设A、B是两个非空的集合,如果按某一个确定的对应法则f,使对于集合A中的任意一个元素x,在集合B中都有唯一确定的元素y与之对应,那么就称对应f:A B为从集合A到集合B的一个映射记作“f:A B”

给定一个集合A到B的映射,如果a∈A,b∈B且元素a和元素b对应,那么,我们把元素b叫做元素a的象,元素a叫做元素b的原象

说明:函数是一种特殊的映射,映射是一种特殊的对应,①集合A、B及对应法则f是确定的;②对应法则有“方向性”,即强调从集合A到集合B的对应,它与从B到A的对应关系一般是不同的;③对于映射f:A→B来说,则应满足:(Ⅰ)集合A中的每一个元素,在集合B中都有象,并且象是唯一的;(Ⅱ)集合A中不同的元素,在集合B中对应的象可以是同一个;(Ⅲ)不要求集合B中的每一个元素在集合A中都有原象

6. 常用的函数表示法及各自的优点:

○1 函数图象既可以是连续的曲线,也可以是直线、折线、离散的点等等,注意判断一个图形是否是函数图象的依据;○2 解析法:必须注明函数的定义域;○3 图象法:描点法作图要注意:确定函数的定义域;化简函数的解析式;观察函数的特征;○4 列表法:选取的自变量要有代表性,应能反映定义域的特征.

注意啊:解析法:便于算出函数值列表法:便于查出函数值图象法:便于量出函数值

补充一:分段函数 (参见课本P24-25)

在定义域的不同部分上有不同的解析表达式的函数在不同的范围里求函数值时必须把自变量代入相应的表达式分段函数的解析式不能写成几个不同的方程,而就写函数值几种不同的表达式并用一个左大括号括起来,并分别注明各部分的自变量的取值情况.(1)分段函数是一个函数,不要把它误认为是几个函数;(2)分段函数的定义域是各段定义域的并集,值域是各段值域的并集.

补充二:复合函数

如果y=f(u),(u∈M),u=g(x),(x∈A),则 y=f[g(x)]=F(x),(x∈A) 称为f、g的复合函数

例如: y=2sinX y=2cos(X2+1)

7.函数单调性

(1).增函数

设函数y=f(x)的定义域为I,如果对于定义域I内的某个区间D内的任意两个自变量x1,x2,当x1

函数式编程和面向对象编程各有利弊,一个语法更加自由,一个健壮性更好。作为程序员应该对两种编程方式都有所了解,不管是哪种方式,只要能够很好的解决当前的问题就是正确的方式,毕竟对于软件工程来说解决问题是最主要的,用的工具反而没有那么重要,就像对程序员来说语言不重要,重要的是解决问题的思想。

现在这两者的发展趋势是相互借鉴的,许多以面向对象作为基础的语言例如Java等都在新的版本中添加了对函数式编程的支持,而函数式编程则借鉴了一些在面向对象语言里用的一些编译技巧使得程序运行更快

主要有以下原因:

Functions as first-class values, 函数一等公民, 可以把函数作为参数传递, 从而构造出高阶函数各种用法 这个用法各种语言都支持了: Lua 支持, Python 似乎也支持, Java 也开始支持了, 我会的语言少都举不出来不支持传函数的流行语言

Pure functions, 纯函数 可以写, 但也有很大区别 JavaScript 没限制, 从而不能预判函数纯或者不纯 Clojure 遵循 Lisp 风格的约定, 带副作用的函数一般用 `f!` 这种叹号结尾的写法命名, 而编译器没有约束 Haskell 是严格约束的, 出了名的 IO Monad 就是因为遵循纯函数导致副作用难以直接用数学函数表达出来, 最终精心设计出一个概念

Referential transparency, 引用透明, 所以表达式可以被其运算结果完全替换掉, 也就是要求控制甚至避免副作用 

Controlled effects, 受控的副作用, 主要手段是隔离 JavaScript 需要人为地去隔离, 语言层面完全没有限制 Clojure 也需要人为隔离, 就像前面说的 `f!` 那样的约定, 同时规定了数据不可变, 再加上作者有意在语言中强调控制副作用, 实际上副作用少得多 Haskell 通过类型系统限定, 不隔离副作用无法通过编译的

Everything is an expression, 一切皆是表达式 JavaScript 做不到, 导致设计 DSL 时候很头疼, 倒是 CoffeeScript 做到了 Clojure 继承了 Lisp, 很明显一切皆是表达式 Haskell 代码里都是函数, 除了类型声明和语法糖部分, 也是一切皆是表达式

No loops, 换句话说, 不能用 for/while, 因为这两个写法当中的 `i++` 依赖可变数据 JavaScript 经常使用 for/while Clojure 当中的循环基本上用尾递归实现, 同时也提供了 doseq 之类的 Macro 让循环过程很好写 Haskell 就是完全尾递归的写法了

Immutable values JavaScript 默认可变, 仅有的手段用 `Objectfreeze` 可以强行锁定对象或者 const 锁定变量本身, 另外就是 immutable-js 那样的共享结构的不可变数据作为类库来实现 Clojure 是把不可变数据和结构共享作为语言的基础, 专门设计了 Atom 类型用于模拟共享的可变状态, 也不排除某些场景和宿主语言的互 *** 作还是会有可变数据 Haskell 默认就是不可变数据, 也有 IORef 相关的代码可以模拟可变状态, 但在教程里几乎看不到

Algebraic Datatypes, 代数类型系统 JavaScript 没有静态类型系统, TypeScript 有类型, 但和代数类型还不一样 Clojure 没有静态类型系统, 就算有而只是很基础的类型检查, 或者用 Specs 做详细运行时检查 Haskell 有强大的代数类型系统, 即便是副作用也被涵盖在类型系统当中

Product types Haskell 通过代数类型系统支持

No Null JavaScript 当中有 undefined 和 null Clojure 当中只有 nil Haskell 里没有 null 也没有 nil, 而是用了 Maybe Monad 这样的概念, 通过类型系统进行了抽象和限制 null 的问题很深, 网上找解释吧, 我还没理解清楚, 只了解到满足了方便却造成了意料之外的复杂度

A function always returns a value, 函数永远都有返回值, 类似一切皆是表达式那个问题 比如 Haskell 里会有的叫做 Unit 的 `()` 空的值 这个有点费解

Currying, 柯理化 JavaScript 和 Clojure 也能模拟, 而在 Haskell 当中是默认行为

Lexical scoping, 词法作用域 三者都支持

Closures, 闭包, 都支持

Pattern matching, 模式匹配 类似解构赋值之类的在 JavaScript 和 Clojure 当中通过语法糖也算有这个功能, 但是跟 Haskell 以及 Elixir 当中的用法对比起来差距很大 比如说 Haskell 甚至能定义 `let 1 + 1 = 3` 来覆盖 `+` 的行为, 虽然是奇葩的现象, 但这就是一个定义的 pattern, 在 JavaScript 和 Clojure 都没有这种情况

Lazy evaluation, 惰性计算 JavaScript 是严格求值的, 不支持惰性计算 Clojure 支持 Lazy, 然而由于 Clojure 又允许了一些副作用, 实际上某些特殊场景会需要手动 force 代码执行, 也就是说不完美 Haskell 采用惰性计算 惰性计算就是说代码里的表达式被真正使用来才会真正执行, 否则就像是个 thunk, 继续以表达式存储着 我印象里 Elm 社区说过, 对于图形界面来说 Lazy 反而是多余的

    大致做个总结, 就是 Haskell 当中的类型系统, 不可变数据, 控制副作用, 在 Clojure 当中只是做了不可变数据, 同时稍微控制了一下副作用, 而这些概念在 JavaScript 当中很少有支持 这样的结果, JavaScript 写出来的代码几乎都是不符合函数式编程的限制得

最简单的apply无非就是这个样子:

template <typename Fp, typename Args>

inline auto apply(Fp&& f, Args&& args)

-> decltype(std::forward<Fp>(f)(std::forward<Args>(args)))

{ return std::forward<Fp>(f)(std::forward<Args>(args)); }

如果你还要apply class member function之类的东西再加几个特化就行:

template <class Fp, typename A0, typename Args>

inline auto apply(Fp&& f, A0&& a0, Args&& args)

-> decltype((std::forward<A0>(a0)f)(std::forward<Args>(args)))

{ return (std::forward<A0>(a0)f)(std::forward<Args>(args)); }

template <typename Fp, typename A0>

inline auto apply(Fp&& f, A0&& a0) -> decltype(std::forward<A0>(a0)f)

{ return std::forward<A0>(a0)f; }

template <typename Fp, typename A0, typename Args>

inline auto apply(Fp&& f, A0&& a0, Args&& args)

-> decltype(((std::forward<A0>(a0))f)(std::forward<Args>(args)))

{ return ((std::forward<A0>(a0))f)(std::forward<Args>(args)); }

template <typename Fp, typename A0>

inline auto apply(Fp&& f, A0&& a0) -> decltype((std::forward<A0>(a0))f)

{ return (std::forward<A0>(a0))f; }

我们前篇谈了很多关于闭包的理解了,所以你应该会知道,我们现在将要谈的就是 ——异步。

我们为什么觉得“异步问题”复杂呢?

其中很重要的一个原因是 —— 时间!时间将我们对数据的 *** 作、管理,变复杂了好几个量级!

(需要特别提出并明确的是: 异步和同步之间是可以相互转化的! 我们使用异步或者同步取决于 —— 如何使代码更加可读!)

函数式编程给出了实现“代码更可读”的落地原则(已多次回顾):

所以我们可以期待,异步在函数式编程中的表现!

上代码:

onCustomer() 和 onOrders() 是两个回调函数释义,两者执行的先后顺序并不能确定,所以它是一个基于时间的复杂状态。

释义:回调函数其实就是一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。

通常来说,我们最先想到的是:把 lookupOrders() 写到 onCustomer() 里面,那我们就可以确认 onOrders() 会在 onCustomer() 之后运行。

这样写,对吗?

不对!因为 onCustomer() 、 onOrders() 这两个回调函数的关系更像是一种竞争关系(都是赋值 customerorders ), 它们应该并行执行 而不是串行执行

即:我不管你们谁先执行,谁先执行完,谁就赋值给 customerorders !

那我们的思路应该是:

不过,这样让代码又变得更加难阅读!!函数内部赋值依赖于外部变量、甚至受外部回调函数的影响。

那究竟怎么办呢?

最终,我们借用 JS promise 减少这个时间状态,将异步转成同步:

两个 then() 运行之前, lookupCustomer() 和 lookupOrders() 已被同步调用,满足并行执行,谁先结束,谁赋值给 customerorders ,所以我们不需要知道谁先谁后!

在这样的实现下,不再需要时间先后的概念!减少了时间状态!!代码的可读性更高了!!

这是一个 积极的数组 ,因为它们同步(即时)地 *** 作着离散的即时值或值的列表/结构上的值。

什么意思?

a 映射到 b,再去修改 a ,b 不会收到影响。

而这,是一个 惰性的数组 , mapLazy() 本质上 “监听” 了数组 a,只要一个新的值添加到数组的末端(push()),它都会运行映射函数 v => v 2 并把改变后的值添加到数组 b 里。

什么意思?

a 映射到 b,再去修改 a ,b 也会修改。

原来,后者存在 异步 的概念。

让我们来想象这样一个数组,它不只是简单地获得值,它还是一个懒惰地接受和响应(也就是“反应”)值的数组,比如:

设置“懒惰的数组” a 的过程是异步的!

b ,是 map 映射后的数组,但更重要的是,b 是 反应性 的,我们对 b 加了一个类似监听器的东西。

这里直接给出解答:

这里再多小结一句:时间让异步更加复杂,函数式编程在异步下的运用就是减少或直接干掉时间状态。

想象下 a 还可以被绑定上一些其他的事件上,比如说用户的鼠标点击事件和键盘按键事件,服务端来的 websocket 消息等。

上述的 LazyArray 又可叫做 observable !(当然,它不止用在 map 方法中)

现在已经有各种各样的 Observables 的库类,最出名的是 RxJS Most

以 RxJS 为例:

不仅如此,RxJS 还定义了超过 100 个可以在有新值添加时才触发的方法。就像数组一样。每个 Observable 的方法都会返回一个新的 Observable,意味着他们是链式的。如果一个方法被调用,则它的返回值应该由输入的 Observable 去返回,然后触发到输出的 Observable里,否则抛弃。

比如:

本篇介绍了异步在函数式编程中的表现。

原则是:对于那些异步中有时态的 *** 作,基础的函数式编程原理就是将它们变为无时态的应用。即 减少时间状态

就像 promise 创建了一个单一的未来值,我们可以创建一个积极的列表的值来代替像惰性的observable(事件)流的值。

我们介绍了 RxJS 库,后续我们还会介绍更多优美的 JS 函数式编程库!

(俗话说的好,三方库选的好,下班都很早!!)

现在本瓜有点明白那句话了:看一门语言是不是函数式编程,取决于它的核心库是不是函数式编程。

也许我们还不熟悉像 RxJS 这类库,但我们慢慢就会越来越重视它们,越来越使用它们,越来越领会到它们!!

异步,以上。

函数表达式是用一个数学等式把x、x的关系表示出来,也称为函数关系式、函数解析式。

函数解析式,是函数表达方式。函数与函数解析式是完全不同的两个概念。

函数是指两个变量A与B之间,如果A随着B的每个值,都有唯一确定的值与之对应,那么A就是B的函数。

从对应角度理解,有两种形式:

1、一对一,就是一个B值对应一个A值,反之,一个A值也对应一个B值(当然,此时B也是A的函数)。

2、一对多,就是多个B值对应一个A值。(此时一个A值对应多个B值,所以B不是A的函数)。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/12184950.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存