Skip to content

Instantly share code, notes, and snippets.

@nuttycom
Created March 17, 2012 19:24
Show Gist options
  • Save nuttycom/2064503 to your computer and use it in GitHub Desktop.
Save nuttycom/2064503 to your computer and use it in GitHub Desktop.
Typeclasses and the Strategy pattern
// first, the Strategy pattern, in Java:
interface AdditionStrategy {
public int add(int a1, int a2);
}
// A simple polymorphic version - abstract over the type being added
interface PolyAdditionStrategy<A> {
public A add(A a1, A a2);
}
class UsesAdditionStrategy {
// typical "Strategy Pattern" call
public static int add(int a, AdditionStrategy adder) {
return adder.add(a, a);
}
// polymorphic "Strategy Pattern" call
public static <A> A addPoly(A a, PolyAdditionStrategy<A> adder) {
return adder.add(a, a);
}
}
--suppose I wanted to do something crazy like reverse the arguments to fmap, to make it look more like Scala
myfmap :: Functor f => f a -> (a -> b) -> f b
myfmap fa f = fmap f $ fa
Prelude> myfmap [1, 2, 3, 4] (+1)
[2,3,4,5]
// the Semigroup typeclass
trait Semigroup[A] {
def append(a1: A, a2: => A): A
}
object Semigroup {
//first-order "implicit typeclass pattern" call
def append[A: Semigroup](a: A) = implicitly[Semigroup[A]].append(a, a)
}
//now higher-kinded:
trait Functor[F[_]] {
def fmap[A, B](fa: F[A])(f: A => B): F[B]
}
object Functor {
def fmap[A, B, F[_]: Functor](fa: F[A])(f: A => B) = implicitly[Functor[F]].fmap(fa)(f)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment