丰联汽配网站建设成本石家庄外贸网站建设公司排名
news/
2025/9/24 2:46:40/
文章来源:
丰联汽配网站建设成本,石家庄外贸网站建设公司排名,网站开发毕业设计源码,网站建设流程分为三个步骤computation expression之一问三不知
计算表达式是一个有点难理解的东西。我把帮助全部看了一遍#xff0c;记住了个上下文敏感的计算#xff08;contex-sensitive computation#xff09;。但是让我讲计算表达式是什么#xff1f;为什么#xff1f;怎么做#xff1f;我…computation expression之一问三不知
计算表达式是一个有点难理解的东西。我把帮助全部看了一遍记住了个上下文敏感的计算contex-sensitive computation。但是让我讲计算表达式是什么为什么怎么做我是满头雾水。我大概知道是什么就是一个语法特征在一个表达式上下文中使用诸如let!return这些语法实现与上下文紧密相关的特殊计算。我甚至还能侃侃而谈上下文相关、如何构造某个特殊表达式match!是let!的语法糖之类的。
到底为什么我不能回答。
奇妙的option计算
还是让我们从一个实际的问题出发。我教了一个班只有两个学生我有点点满意一个叫isaac一个叫mike其他人我根本不想理会。要实现一个全班评价的函数。
let rateStudent name match name with| isaac - Some 90| mike - Some 80| _ - None这个函数的ADT就是val rateCustomer: name: string - int option。
下面的问题是有两个学生问我给他们评价的总分是多少我这个人比较龟毛只有有一个学生是我不想理会的那么我就不置可否None。
实现起来看起来也挺简单
let commentTwo name1 name2 let result1 rateStudent name1let result2 rateStudent name2match result1, result2 with| Some r1, Some r2 - Some(r1 r2)| _ - None 或者我们在学会一个Option.bind之后还能写成
let commentTwoAlt name1 name2 let result1 rateStudent name1let result2 rateStudent name2result1 | Option.bind (fun x -result2 | Option.bind (fun y -Some (x Y)))这里面我们的Option.bind的原型就是在MSDN中给出为bind f inp match inp with None - None | Some x - f x。
这两种方式都行如果两个学生都是我认可的那么给出答案Some 170其他任何情况我都是不予理会None。
接下来事情可能变得有趣起来。假设我有100个学生其中50个我觉得差强人意评了个分数其他的50个继续是不予理会。
怎么办如果我不是求两个学生的和而是要进行其他的计算怎么办
Computation Expression版龟毛老师
这里的问题挺简单就是要处理int option和一个返回int option的函数rateStudent。
首先我们定义一个Builder。
type Maybe() member this.Bind(opt, func) opt | Option.bind funcmember this.Return v Some v这个Builder定义了两个操作一个是绑定一个是返回。然后实例化一个builder。
let maybe Maybe()接下来就能开心的用计算表达式来处理任意复杂的计算
let answer maybe {// binding int option to int let! first rateStudent isaaclet! second rateStudent mikelet! third rateStudent isaac// calculation using intlet total first second third// return float option from floatreturn (float total) / 3.0}上面这个值是一个float option当我们计算中任何一个rateStudent返回None计算表达式就会马上输出None。
我们在上面插入一些printfn更改rateStudent的参数就会发现只要任何一个地方出现None的绑定马上就返回None。
let answer maybe {printfn 0let! first rateStudent isaacprintfn 1let! second rateStudent mikeprintfn 2let! third rateStudent isaacprintfn 3let total first second thirdprintfn returnreturn (float total) / 3.0}如果第一个名字isaac打错的话就只会打印0把None绑定到answer非常神奇。
优点
上面这种实现的优点有哪些
在maybe中let!绑定变量的类型是int而不是int option后续的计算完全不用处理option的问题就当做是没有option龟毛老师这回事返回的类型是float而不需要写作Some float。
疑点
这里的Return比较容易理解就是把一个值包装成Some。但是Bind是怎么工作的呢我们看看Maybe的定义
type Maybe() member this.Bind(opt, func) opt | Option.bind func这里我们调用的时候let! first rateStudent isaac第一个值好理解是一个int option刚好符合Option.bind的第一个参数。但是第二个参数func是什么呢
这里的疑问其实是let在F#中特殊用途。按照函数式编程的概念并没有什么全局变量的概念。而let看起来是定义了一个全局变量。
let x 10
printfn %A x定义变量访问变量多么熟悉啊。但是这里的let其实是一个语法糖它的本质是一个函数调用。
let x 10 in
printfn %A x或者
let x 10 in printfn %A x本质上是
10 | (fun x - printfn %A x)这样写就清楚多了。
那么我们这下就能够明白为什么定义绑定的时候第二个参数是一个函数了。因为let!的本质是一个函数调用而Option.bind的第二个参数就是一个函数。实际上这里的函数实际上就是后续的所有表达式组成的一个函数。
let answer maybe {let! first rateStudent isaac inlet! second rateStudent mike inlet! third rateStudent isaac inlet total first second third inreturn (float total) / 3.0}或者 maybe.Bind (rateStudent isaac) (fun first -maybe.Bind (rateStudent mike) (fun second -maybe.Bind (rateStudent isaac) (fun third -let total first second thirdreturn (float total) / 3.0)))这样的话我们就更清楚Bind函数的表达式为什么是那么样子而上面的计算表达式中firstsecondthirdtotal都是int而不是int option了。
结论
处理int option的Builder把int option的计算表达式转换成了int的计算表达式这就是计算表达式的作用让我们在上下文中编写表达式表达我们所想要关注的计算把option的处理逻辑放在上下文中隐含处理这里只涉及到两个表达式let!return更多的构造接下来再说。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/914637.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!