zoukankan      html  css  js  c++  java
  • F# ——Computation 表达式

    或许你对这个词有点陌生,但是如果说到F#中的Sequence表达式,Async结构时,你或许会有点印象。其实这两种表达式均可以理解为Computation Expression.

    如果你对Sequence表达式这个名词感觉很陌生的话,那先弄些代码来看看:

    let seqExpr = 
        seq{
            for i in [1..10] do
                yield i
        }

    相信看到上面的代码你应该知道神马叫Sequence表达式了。。。

    下面是Async的代码片断:

    let asyncExpr path = 
        async{
                let fileStr = new System.IO.FileStream(path,System.IO.FileMode.Open) 
                use strRdr = new System.IO.StreamReader(fileStr)
                while not strRdr.EndOfStream do
                    let line  = strRdr.ReadLine()
                    printfn "%s" line                       
        } |> Async.RunSynchronously

    Async 和 Seq 中的那关键字都是有它自己的功能的,那么这些关键字是怎么定义的呢,下面就来自定义一个这样的表达式玩玩:

        [<Measure>]
        type 米
        [<Measure>]
        type 秒
        [<Measure>]
        type 米每秒 = 米 / 秒
    
        type Velocity<[<Measure>] 'T> =
            | MovingOrStop of float<'T>        
            | Illegal
        let cal m s  =
            match s with
            | 0.<秒> -> Illegal
            | _     -> MovingOrStop(m/s)
        type CalVelocityBuilder() =        
            let mutable speed = 0.0<米每秒>
            member this.Yield(()) =
                speed
    
            member this.Bind(v : Velocity<米每秒>,func : float<米每秒> -> float<米每秒>) =
                match v with
                | Illegal -> speed <- -1.<米每秒>; speed
                | MovingOrStop(value) -> func value
                
            member this.Return(v : float<米每秒>) = v        
    
        let V = new CalVelocityBuilder()
        let 速度 =
            V {                      
                let! k = cal 1.0<米> 5.0<秒>                               
                return k
            }

     代码自定义了let!关键字,这是通过member this.Bind(v : Velocity<米每秒>,func : float<米每秒> -> float<米每秒>)函数实现的,它的MSDN 描述 如下: 

    Method

    Typical signature(s)

    Description

    Bind

    M<'T> * ('T -> M<'U>) -> M<'U>

    Called for let! and do! in computation expressions.

    代码中的 米 ,秒 ,和 米每秒都是 自定义的测量单位。

    上面代码在FSI中的运行结果:

      val 速度 : float<米每秒> = 0.2

    个人的理解就是: 定义的bind函数 以及 表现为关键字let!,其作用都是为了在执行这一步操作的同时检查是不是有不合法的结果出现,如果有,即跳出这个流程(workflow),这样做是为了弥补F#中没有return,break这样的异常跳出操作。

    Computation 表达式可以再一定程度上减少代码量—— 当你需要经常使用某些特定的代码处理流程的时候。Async就是个例子。

    下面是MSDN关于computation Expression 的描述:

    http://msdn.microsoft.com/en-us/library/dd233182.aspx

    Don Syme(F#创始人)关于这个的解释:

    http://blogs.msdn.com/b/dsyme/archive/2007/09/22/some-details-on-f-computation-expressions-aka-monadic-or-workflow-syntax.aspx

    要完全实现表中的那些函数,需要对Computation更深入的了解。

  • 相关阅读:
    chrome安装vue-devtools
    企业网络设计
    nginx的安装
    Typora 的使用
    如何学习dubbo?
    关于原码反码和补码以及byte&0xff
    HttpClient以及连接池的使用
    计算机网络读书笔记:tcp面试常见问题都在里面了
    接口类是否继承自Object?
    数据挖掘会议记录
  • 原文地址:https://www.cnblogs.com/FsharpZack/p/2783110.html
Copyright © 2011-2022 走看看