Last active
August 4, 2016 22:50
-
-
Save salanki/afc1e1328ad75b0876daa513b179187b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Actions.scala */ | |
package actions | |
trait Action // Trait ~= abstract class / interface. Can't be directly instantiated. | |
sealed trait Feed extends Actions // Sealing is not required but important as the compiler will know that this class can't be extended by any other code, meaning we can do static typechecking that anything that is supposed to handle all cases of Feed actually does so. More reading: http://underscore.io/blog/posts/2015/06/02/everything-about-sealed.html | |
/* Objects are often used similar to packages in Scala. In this case you can just think of them as a grouping, no other special meaning */ | |
object Feed { | |
class FetchRequest extends Feed | |
class FetchReply(payload: String) extends Feed | |
} | |
/* Reducers.scala */ | |
package reducers | |
/* The trait and reduce method below would come with the "Redux library" */ | |
trait Reducer[A] { | |
def reduce(store: String, action: A): String | |
} | |
def reduce[A: Action](store, action) = { | |
implicitly[Reducer[A]].reduce(store, action) | |
} | |
/* User code */ | |
object FeedReducer { | |
implicit object FetchRequest extends Reducer[actions.Feed.FetchRequest] { | |
def reduce(store: String, action: actions.Feed.FetchRequest) = store | |
} | |
implicit object FetchReply extends Reducer[actions.Feed.FetchReply] { | |
def reduce(store: String, action: actions.Feed.FetchReply) = action.payload | |
} | |
} | |
object SomeOtherReducer { | |
implicit object FetchReply extends Reducer[actions.Feed.FetchReply] { | |
def reduce(store: String, action: actions.Feed.FetchReply) = action.payload | |
} | |
} | |
object CombinedReducer { | |
implicit object FetchReply extends Reducer[actions.Feed.FetchReply] { | |
// Function composition composes the two reducers into one that takes the same parameters | |
val reduce = implicitly[FeedReducer.FetchReply].reduce compose implicitly[SomeOtherReducer.FetchReply] | |
} | |
} | |
// I could have one reducer that handles all type of feed actions if I wanted, ie: | |
object Feed { | |
implicit object All extends Reducer[Feed] { | |
def reduce(store: String, action: actions.Feed) = dispatchSomewhereElse | |
} | |
} | |
// The code running the reducer would then do | |
import CombinedReducer._ | |
reduce(store, action) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment