trait M[A] {
def flatMap[B](f: A => M[B]): M[B]
}
def unit[A](x: A): M[A]
*/
object MonadDemo {
def f1(x: Int) = {
(x + 1, x + "+1")
}
def f2(x: Int) = {
(x + 2, x + "+2")
}
def f3(x: Int) = {
(x + 3, x + "+3")
}
// ----
def unit(x: Int) = {
(x, "Ops: ")
}
def bind(t: Tuple2[Int, String], f: Int => Tuple2[Int, String]) = {
var res = f(t._1)
(res._1, t._2 + res._2 + ";")
}
def main(args: Array[String]): Unit = {
/*
(a,b) -> c
a -> (b -> c)
a -> b -> c
*/
def add(a: Int, b: Int) = {
a + b
}
def curry_add(a: Int) = {
def add0(b: Int) = {
a + b
}
add _
}
// add(1,3) == curry_add(1)(3)
// val add3 = curry_add(_)(3)
// add3(5)
// ----- code example ----
// some business code to process data
var log = "Ops: "
var input = 0
var (res1, log1) = f1(input)
log += log1 + ";"
var (res2, log2) = f2(res1)
log += log2 + ";"
var (res3, log3) = f3(res2)
log += log3 + ";"
println(res3, log)
// we want this f3(f2(f1(x))), but f1 return are not f2 params
// ----------- so transform to monad -----
println(bind(bind(bind(unit(input), f1), f2), f3) + " - high-level function version")
// pipeline
// type ft = Int => Tuple2[Int, String]
def pipleline(e: Tuple2[Int, String], fList: List[Int => Tuple2[Int, String]]) = {
var e1 = e
for (f <- fList) {
e1 = bind(e1, f)
}
e1
}
println(pipleline(unit(input), List(f1, f2, f3)) + " - monad version")
// ----------- map monad -----
// Seq(unit(input))
// .map(x => bind(x, f1))
// .map(x => bind(x, f2))
// .map(x => bind(x, f3))
val resMonad = Seq(unit(input))
.map(bind(_, f1))
.map(bind(_, f2))
.map(bind(_, f3))
.head
println(resMonad + " - map manod version")
// ---- process Documents demo ---
processDocumentsDemo()
}
def processDocumentsDemo(): Unit = {
val documents = Seq(Document(), Document(), Document())
// to find word length greater than 4 in all documents
val wordsList: ListBuffer[Word] = ListBuffer()
documents.foreach(d => {
if (d.sentences != null) {
d.sentences.foreach(s => {
/* anything business code 1*/
if (s.words != null) {
s.words.foreach(w => {
if (w.length > 4) {
wordsList += w
}
/* anything business code 2*/
})
}
})
}
})
// println(wordsList) //get results
// ------- flatMap version ----------
val wordList2: Seq[Word] = documents
.flatMap(d =>
d.sentences.flatMap(s => s.words.filter(w => w.length > 4))) /* anything business code 1*/
.map(w => w) /* anything business code 2*/
// ----- for yield version -----------
val wordList3: Seq[Word] = for {
d <- documents
s <- d.sentences
w <- s.words
if w.length > 4
} yield w
// add some business code example
val wordList4: Seq[Word] = for {
d <- documents
s <- d.sentences
w <- bindWord(s, null) // any data process extract as a bind function
if w.length > 4
} yield {
/* anything business code 2 */
w
}
}
def bindWord(s: Sentence, f: Sentence => Seq[Word]): Seq[Word] = {
/* anything business code 1*/
type func = Sentence => Seq[Word]
f match {
case null => s.words
case f: func => f(s)
}
}
}
case class Document() {
val sentences: Seq[Sentence] = Seq()
}
case class Sentence() {
val words: Seq[Word] = Seq()
}
case class Word() {
val length: Int = 6
}
scala Monad demo
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 在Scala代码块中利用“定界符”创建多行字符串 解决方法: 在Scala中,利用三个双引号包围多行字符串配合...
- 方式清单 (先将jar包导完后) 方式一思路将数据库连接有关的信息配置到db.properties里为了方便跟进程...
- http://www.cnblogs.com/cbscan/articles/4147709.html
- 1. Scala概述 1.1什么是Scala Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和...