Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Generally you are using a typeclass to specify behavior (which I guess is a kind of duck-typing).

For example, there is a typeclass Foldable[F[_]] which provides the ability to "fold" (i.e. recurse over) some type F[_] which takes a type parameter. Then you have typeclass definitions for Foldable[Set], Foldable[List], Foldable[Tree], Foldable[Option], etc.

Then if you have an operation and you want it to work on any collection that can be folded, then you can just define it in terms of a generic type that has a Foldable typeclass. For instance to generically sum a collection of ints, you might do

def sum[F[_] : Foldable](ints: F[Int]): Int = ...

Now you can call sum(List(1,2,3)), sum(Set(1,2,3)), sum(Option(1)), etc...



Typeclass instance = Adaptor/Decorator in OOP terms, automatically derived (and wrapped in) for you by the compiler.

You want to fold over Options? Make a FoldableOption class implementing Foldable<Option> and pass "new FoldableOption(myOptionValue)" to whatever places you need. Haskell does pretty much the same (unless they moved away from dictionary passing).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: