Scala本质论:学习Scala的6个核心概念


Essential Scala Noel Welsh, @noelwelsh underscore Six Core Concepts for Learning Scala Introduction Scala is complex? Self types
 Type bounds
 Existential types Trait stacks
 Overloading
 Implicit conversions Is doesn’t have to be this way 1. Expressions, types, & values 2. Objects and classes 3. Algebraic data types 4. Structural recursion 5. Sequencing computation 6. Type classes 1. Expressions, types, & values 2. Objects and classes 3. Algebraic data types 4. Structural recursion 5. Sequencing computation 6. Type classes Huge thanks to the PLT team
 http://racket-lang.org/ people.html Algebraic Data Types Goal: translate data descriptions into code Model data with logical ors and logical ands A website visitor is: • logged in; or • anonymous A logged in user has: • an ID; and • an email address Structure of the code follows the structure of the data Two patterns: • product types (and) • sum types (or) Product type: 
 A has a B and C 
 A has a B and C final case class A(b: B, c: C) 
 A has a B and C final case class A(b: B, c: C) 
 A has a B and C final case class A(b: B, c: C) 
 A has a B and C final case class A(b: B, c: C) Sum type: 
 A is a B or C 
 A is a B or C sealed trait A final case class B() extends A final case class C() extends A 
 A is a B or C sealed trait A final case class B() extends A final case class C() extends A 
 A is a B or C sealed trait A final case class B() extends A final case class C() extends A 
 A is a B or C sealed trait A final case class B() extends A final case class C() extends A Sum and product together make algebraic data types Examples A website visitor is: • logged in; or • anonymous sealed trait Visitor final case class Anonymous()
 extends Visitor final case class User()
 extends Visitor A logged in user has: • an ID; and • an email address An anonymous has: • an ID sealed trait Visitor { def id: Id } final case class Anonymous(id: Id)
 extends Visitor final case class User(id: Id, email: Email)
 extends Visitor A calculation is a success or failure sealed trait Calculation final case class Success()
 extends Calculation final case class Failure()
 extends Calculation A success has a value. 
 A failure has an error message sealed trait Calculation final case class Success(value: Int)
 extends Calculation final case class Failure(msg: String)
 extends Calculation Summary • Structure data with logical ands and ors • These are called algebraic data types • Code follows immediately from structure of the data Structural Recursion Goal: transform algebraic data types sealed trait Calculation final case class Success(value: Int)
 extends Calculation final case class Failure(msg: String)
 extends Calculation Implement on Calculation def add(value: Int): Calculation = ??? Structure of the code follows structure of the data Two (sub-)patterns: pattern matching and polymorphism A is a B or C
 B has a D and E
 C has a F and G sealed trait A final case class B(d: D, e: E) extends A final case class C(f: F, g: G) extends A Pattern matching sealed trait A { def doSomething: H = { this match { case B(d, e) => doB(d, e) case C(f, g) => doC(f, g) } } } final case class B(d: D, e: E) extends A final case class C(f: F, g: G) extends A Polymorphism sealed trait A { def doSomething: H } final case class B(d: D, e: E) extends A { def doSomething: H = doB(d, e) } final case class C(f: F, g: G) extends A { def doSomething: H = doC(f, g) } Example sealed trait Calculation final case class Success(value: Int)
 extends Calculation final case class Failure(msg: String)
 extends Calculation Add an Int to a Calculation sealed trait Calculation { def add(value: Int): Calculation = ??? }
 final case class Success(value: Int) 
 extends Calculation 
 final case class Failure(msg: String) 
 extends Calculation sealed trait Calculation { def add(value: Int): Calculation = this match { case Success(v) => ??? case Failure(msg) => ??? } } final case class Success(value: Int) 
 extends Calculation final case class Failure(msg: String) 
 extends Calculation sealed trait Calculation { def add(value: Int): Calculation = this match { case Success(v) => 
 Success(v + value) case Failure(msg) => 
 Failure(msg) } } final case class Success(value: Int) 
 extends Calculation final case class Failure(msg: String) 
 extends Calculation Summary • Processing algebraic data types immediately follows from the structure of the data • Can choose between pattern matching and polymorphism • Pattern matching (within the base trait) is usually preferred Sequencing Computation Goal: patterns for sequencing computations Functional programming is about transforming values That is all you can do without introducing side- effects A => B => C This is sequencing computations Three patterns: fold, map, and flatMap A B=> Fold Abstraction over structural recursion sealed trait A { def doSomething: H = { this match { case B(d, e) => doB(d, e) case C(f, g) => doC(f, g) } } } final case class B(d: D, e: E) extends A final case class C(f: F, g: G) extends A sealed trait A { def doSomething: H = { this match { case B(d, e) => doB(d, e) case C(f, g) => doC(f, g) } } } final case class B(d: D, e: E) extends A final case class C(f: F, g: G) extends A sealed trait A { def fold(doB: (D, E) => H, doC: (F, G) => H): H = { this match { case B(d, e) => doB(d, e) case C(f, g) => doC(f, g) } } } final case class B(d: D, e: E) extends A final case class C(f: F, g: G) extends A Example A Result is a Success or Failure sealed trait Result final case class Success() extends Result final case class Failure() extends Result Success contains a value of type A sealed trait Result[A] 
 final case class Success[A](value: A) 
 extends Result[A]
 final case class Failure[A]() 
 extends Result[A] (This just an invariant Option) Implement fold Start with structural recursion pattern sealed trait Result[A] { def fold[B]: B = this match { Success(v) => ??? Failure() => ??? } } final case class Success[A](value: A) 
 extends Result[A] final case class Failure[A]() 
 extends Result[A] Abstract out arguments sealed trait Result[A] { def fold[B](s: A => B, f: B): B = this match { Success(v) => s(v) Failure() => f } } final case class Success[A](value: A) 
 extends Result[A] final case class Failure[A]() 
 extends Result[A] Fold is a generic transform for any algebraic data type Fold is not always the best choice Not all data is an algebraic data type Sometimes other methods are easier to use Result[A] Get user from database (might not be a user) Convert user to JSON Result[User] Result[User] User => Json Result[Json] Map A B=>F[A] F[B] map = Get user from database (might not be a user) Get order for user (might not be an order) Result[User] Result[User] User => Result[Order] Result[Order] FlatMap A F[B]=>F[A] F[B] flatMap = Example getOrder(id: UserId): 
 HttpResponse Order => Json UserId UserId => Result[User] User => Result[Order] Result[Json] => HttpResponse Order => Json UserId UserId => Result[User] User => Result[Order] Result[Json] => HttpResponse Order => Json UserId UserId => Result[User] User => Result[Order] Result[Json] => HttpResponse ??? Order => Json UserId UserId => Result[User] User => Result[Order] Result[Json] => HttpResponse flatMap Order => Json UserId UserId => Result[User] User => Result[Order] Result[Json] => HttpResponse Order => Json UserId UserId => Result[User] User => Result[Order] Result[Json] => HttpResponse ??? Order => Json UserId UserId => Result[User] User => Result[Order] Result[Json] => HttpResponse map Order => Json UserId UserId => Result[User] User => Result[Order] Result[Json] => HttpResponse Order => Json UserId UserId => Result[User] User => Result[Order] Result[Json] => HttpResponse ??? Order => Json UserId UserId => Result[User] User => Result[Order] Result[Json] => HttpResponse fold Summary • Standard patterns for sequencing computations • F[A] map (A => B) = F[B] • F[A] flatMap (A => F[B]) = F[B] • fold is general transformation for algebraic data types • You can teach monads in an introductory course! Type Classes Ad-hoc polymorphism Break free from your class oppressors! Concerns that cross class hierarchy E.g. serialize to JSON Common behaviour without (useful) common type Abstract behaviour to a type class Can implement type class instances in ad-hoc manner Conclusions Scala is simple 3 patterns are 90% of code 4 patterns are 99% of code Program design in Scala is systematic 
 underscore.io/training/ courses/essential-scala/
 
 15% off with flatMap Be like keyboard cat!
还剩120页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 6 金币 [ 分享pdf获得金币 ] 1 人已下载

下载pdf

pdf贡献者

cebp

贡献于2015-07-12

下载需要 6 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf