scala akka 修炼之路6(scala函数式柯里化风格应用场景分析)

胜败兵家事不期,包羞忍耻是男儿——斗牛士fighting,fighting,fighting...

小象学习和使用scala也一段时间了,最初小象学习scala主要为了学习spark生态,但是深入学习scala的一些特性后,深深被scala函数式和面向对象的风格所折服,不得不赞美设计这门语言的设计者。小象大学阶段在使用MATLAB做数据分析和自动化设计时,就非常喜欢使用MATLAB的命令行和面向矩阵运算的风格编写分析代码;喜欢使用java编写层次化和清晰的模块接口,而这些Scala语言设计中都有很好的设计。不得不说scala的函数式和面向对象风格,可以让想想随时发生;如果你是画家,使用scala写出来的代码更像一幅充满诗意的风景画。如果你是作家,写出的将是一个扣人心弦的跌宕起伏的大篇。scala给不同类型的程序员不同的体验和感受。而使用scala函数式柯里化风格,可以编写出更加抽象,功能化和高效的函数式代码。

小象在定义主函数功能的时候常常出现这种情况,函数体中的代码越写越长,本来可以拆分的功能,由于写代码的时候逻辑思绪根本停不下来,不愿意中途打断去定义那些繁琐的辅助函数,往往一个函数就一路走到头,最后使主函数代码段很长,不便理解,功能复杂,需要后期慢慢拆分功能。小象在学习使用scala函数式柯里化风格后,在思绪停不下来又需要拆分功能的时候,就将定义好需要拆分的辅助功能函数的声明按照柯里化风格定义在函数声明中,继续完成主函数功能,等主函数功能完成后,在慢慢按照顺序去实现这些辅助功能。为了减少或隐藏辅助功能的传入简化接口中不必要的辅助方法参数传入,可以创建主函数的重载。使用scala柯里化风格可以简化主函数的复杂度,提高主函数的自闭性,提高功能上的可扩张性(事实证明:流水化生产式最高效和安全的,代码编写也一样,一个函数实现维护一个功能的完成处理(逻辑处理,相关异常处理等),也是极简设计,优秀代码体检的追求)。

例如 设计一个获取本地文本文件的所有行数据的功能,主函数功能主要是创建文件流读取文件的所有行,在读取过程中,需要做很多的辅助操作如判断本地文件是否存在和可读和关闭文件流。使用scala的函数式柯里化代码看上去将变得非常优雅

def getLines(filename:String):List[String]={
    getLines(filename)(isReadable)(closeStream)
}
def getLines(filename: String)(isFileReadable: (File) => Boolean)(closableStream: (Closeable) => Unit):List[String] = {
    val file = new File(filename)
    if (isFileReadable(file)) {
      val readerStream = new FileReader(file)
      val buffer = new BufferedReader(readerStream)
      try {
        var list: List[String] = List()
        var str = ""
        var isReadOver = false
        while (!isReadOver) {
          str = buffer.readLine()
          if (str == null) isReadOver = true
          else list = str :: list
        }
        list.reverse
      } finally {
        closableStream(buffer)
        closableStream(readerStream)
      }
    } else {
      List()
    }
  }

  def isReadable(file: File) = {
    if (null != file && file.exists() && file.canRead()) true
    else false
  }
  def closeStream(stream: Closeable) {
    if (null != stream) {
      try {
        stream.close
      } catch {
        case ex => Log.error(“[”+this.getClass.getName+”.closeStream]”,ex.getMessage)
      }
    }
  }

小象认为使用柯里化特性可以将复杂逻辑简单化,并能将很多常漏掉的主函数业务逻辑之外的处理暴露在函数的定义阶段,提高代码的健壮性,使函数功能更加细腻化和流程化。

例如 使用REST风格的HTTP资源请求的基于三层架构的MVC模式的WEB开发中前端的请求服务器段处理过程主要包含:第一步服务器端接受用户资源请求,第二步前端调度器代理接受用户资源请求,第三步检查当前请求的合法性,第四步创建相应的申请过滤处理链处理请求,第五步创建渲染视图,第六步响应用户请求。

如果使用scala编写流程控制函数将非常简单和易于理解

/**
   * 用户资源请求=>调度器代理用户资源请求=>检查请求的合法性=>创建相应的资源申请责任链返回Model数据和视图URI=>创建视图=>响应用户请求
   */
  def serviceUserRequest[IN,M,V,OUT](requstInputData: IN)(dipatcherDelegeteOp: IN => M)(checkRequestValid: M => Boolean)(filterChains: M => M)(createResponseRestURLView: M => V)(createResponseStream:V=>OUT): OUT = {
    val request = dipatcherDelegeteOp(requstInputData)
    if (checkRequestValid(request)) {
      val model = filterChains(request)
      val view=createResponseRestURLView(model)
	 createResponseStream(view)
    } else {
      //error business handler
      “return error view URI Stream"
    }
  }

scala akka 修炼之路6(scala函数式柯里化风格应用场景分析),布布扣,bubuko.com

时间: 2024-10-17 17:58:04

scala akka 修炼之路6(scala函数式柯里化风格应用场景分析)的相关文章

scala akka 修炼之路5(scala特质应用场景分析)

scala中特质定义:包括一些字段,行为(方法/函数/动作)和一些未实现的功能接口的集合,能够方便的实现扩展或混入到已有类或抽象类中. scala中特质(trait)是一个非常实用的特性,在程序设计中能够 更好的抽象现实.使程序更关注各自功能和更好的将程序拆分成多个特质模块,使程序具有更强的扩展性.熟悉java的同学.能够将特质理解为抽象类.可是scala中能够在一个类中同一时候混入多个特质(使用extends 或with).而java中一个类仅仅能继承一个抽象类,假设要实现多个抽象类就必需使用

Go的魅力, 函数式(柯里化, 闭包, 高阶函数), [email protected]装饰器, 封装

Go朴实无华的代码风格是函数式的无尽魅力. 函数式有3个别名, 高大上的"柯里化", 编程语言的"闭包", 数学气息的"高阶函数". Python没有Go的func匿名函数, 但是具有可爱的语法糖(@装饰器). 编程语言都是相通的, 层层封装造就了灵活的风格. 理解了Go的"函数式", 再理解内嵌/接口/重写(设计模式), 剩下的是各个领域的工具了, 就可以写出服务于业务的代码. 感悟于 函数式 http://www.jian

Scala中的柯里化

一.初识Currying柯里化 柯里化(Currying)技术 Christopher Strachey 以逻辑学家 Haskell Curry 命名的(尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的).它是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术. 简单理解就是改变函数的表达形式但其功能特性不变,这对于第一次接触柯里化的人来讲,这样的一个技术貌似有点“鸡肋”,但如果你有丰富的JS

【Scala】高阶函数和柯里化

高阶函数 在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数: - 接受一个或多个函数作为输入 - 输出一个函数 在数学中它们也叫做算子(运算符)或泛函.微积分中的导数就是常见的例子,因为它映射一个函数到另一个函数. 高阶函数的例子 假设有一个函数对给定两个数区间中的所有整数求和: def sumInts(a: Int, b: Int): Int = if(a > b) 0 else a + sumInts(a + 1, b) 如果现在要求连续整数的平方和: def square(x:

Scala函数柯里化(Currying or Curry)

柯里化(Currying) 把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术. 简单的实现如下: scala> def add(x:Int, y:Int) = x + y add: (x: Int, y: Int)Int 假如我们应用的时候,是这样的:add(1,2) 柯里化函数: scala> def add(x:Int)(y:Int) = x + y Curry化最大的意义在于把多个参数的function等价转化成多

Scala 系列(十)—— 函数 & 闭包 & 柯里化

一.函数 1.1 函数与方法 Scala 中函数与方法的区别非常小,如果函数作为某个对象的成员,这样的函数被称为方法,否则就是一个正常的函数. // 定义方法 def multi1(x:Int) = {x * x} // 定义函数 val multi2 = (x: Int) => {x * x} println(multi1(3)) //输出 9 println(multi2(3)) //输出 9 也可以使用 def 定义函数: def multi3 = (x: Int) => {x * x}

JavaScript ES6函数式编程(二):柯里化、偏应用、组合、管道

上一篇介绍了闭包和高阶函数,这是函数式编程的基础核心.这一篇来看看高阶函数的实战场景. 首先强调两点: 注意闭包的生成位置,清楚作用域链,知道闭包生成后缓存了哪些变量 高阶函数思想:以变量作用域作为根基,以闭包为工具来实现各种功能 柯里化(curry) 定义:柯里化是把一个多参数函数转换为一个嵌套的一元函数的过程. 先看个简单的例子,这是一个名为 add 的函数:const add = (x, y) => x + y;调用该函数 add(1, 1).add(1, 2).add(1, 3)...很

Scala学习笔记——简化代码和柯里化

1.简化代码 package com.scala.first import java.io.File import javax.management.Query /** * Created by common on 17-4-5. */ object FileMatcher { def main(args: Array[String]) { for (file <- filesHere) println(file) println() for (file <- filesMatching(&q

Scala Learning(4): Currying柯里化的推演

本文展示加法和乘法的两个例子,最后使用MapReduce的思想把两者统一成一个带Currying的表达形式. 从high-order functions推演到Currying 原始方法 def sum(f: Int => Int, a: Int, b: Int): Int = if (a > b) 0 else f(a) + sum(f, a + 1, b) 表示从a到b,把每个int做一次f处理,把所有结果累加起来. 对应"加法"."立方"."