《Kotlin极简教程》第六章 Kotlin函数式编程(FP)

  1. 云栖社区>
  2. 博客>
  3. 正文

《Kotlin极简教程》第六章 Kotlin函数式编程(FP)

程序员诗人 2017-03-12 00:33:00 浏览664
展开阅读全文

Kotlin对函数式编程的实现恰到好处。

正式上架:《Kotlin极简教程》Official on shelves: Kotlin Programming minimalist tutorial
京东JD:https://item.jd.com/12181725.html
天猫Tmall:https://detail.tmall.com/item.htm?id=558540170670

函数指针

/**
 * "Callable References" or "Feature Literals", i.e. an ability to pass
 * named functions or properties as values. Users often ask
 * "I have a foo() function, how do I pass it as an argument?".
 * The answer is: "you prefix it with a `::`".
 */

fun main(args: Array<String>) {
    val numbers = listOf(1, 2, 3)
    println(numbers.filter(::isOdd))
}

fun isOdd(x: Int) = x % 2 != 0

运行结果: [1, 3]

复合函数

看了下面的复合函数的例子,你会发现Kotlin的FP的实现相当简洁。(跟纯数学的表达式,相当接近了)

/**
 * The composition function return a composition of two functions passed to it:
 * compose(f, g) = f(g(*)).
 * Now, you can apply it to callable references.
 */

fun main(args: Array<String>) {
    val oddLength = compose(::isOdd, ::length)
    val strings = listOf("a", "ab", "abc")
    println(strings.filter(oddLength))
}

fun isOdd(x: Int) = x % 2 != 0
fun length(s: String) = s.length

fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C {
    return { x -> f(g(x)) }
}


运行结果: [a,abc]

简单说明下

val oddLength = compose(::isOdd, ::length)
    val strings = listOf("a", "ab", "abc")
    println(strings.filter(oddLength))

这就是数学中,复合函数的定义:

h = h(f(g))

g: A->B
f: B->C
h: A->C

g(A)=B
h(A) = f(B) = f(g(A)) = C

只是代码中的写法是:

h=compose( f, g )
h=compose( f(g(A)), g(A) )

/**
 * The composition function return a composition of two functions passed to it:
 * compose(f, g) = f(g(*)).
 * Now, you can apply it to callable references.
 */

fun main(args: Array<String>) {
    val oddLength = compose(::isOdd, ::length)
    val strings = listOf("a", "ab", "abc")
    println(strings.filter(oddLength))
    
    println(strings.filter(::hasA))
    println(strings.filter(::hasB))
    
    val hasBStrings = strings.filter(::hasB)
    println(hasBStrings)
    
    val evenLength = compose(::isEven,::length)
    println(hasBStrings.filter(evenLength))
    
    
}

fun isOdd(x: Int) = x % 2 != 0
fun isEven(x:Int) = x % 2 == 0
fun length(s: String) = s.length
fun hasA(x: String) = x.contains("a")
fun hasB(x: String) = x.contains("b")



fun <A, B, C> compose(f: (B) -> C, g: (A) -> B): (A) -> C {
    return { x -> f(g(x)) }
}

fun <W,X,Y,Z> compose2( h: (Y) -> Z, f:(X) -> Y,g:(W) -> X): (W) -> Z {
    return  {x -> h(f(g(x)))} 
}



运行结果:

[a, abc]
[a, ab, abc]
[ab, abc]
[ab, abc]
[ab]

网友评论

登录后评论
0/500
评论
程序员诗人
+ 关注