Skip to content

Instantly share code, notes, and snippets.

@salanki
Last active August 4, 2016 22:50
Show Gist options
  • Save salanki/afc1e1328ad75b0876daa513b179187b to your computer and use it in GitHub Desktop.
Save salanki/afc1e1328ad75b0876daa513b179187b to your computer and use it in GitHub Desktop.
/* 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