Skip to content

Instantly share code, notes, and snippets.

@jonsterling
Created August 28, 2012 15:12
Show Gist options
  • Save jonsterling/3498951 to your computer and use it in GitHub Desktop.
Save jonsterling/3498951 to your computer and use it in GitHub Desktop.
// Which of these do you find easier to scan?
// This is what I imagine you would prefer. No single-char variable
// names. The purpose of every variable is described to the best of my
// ability, though many parameters are just that: parameters.
implicit def KleisliCategory[MonadParam[_]: Monad]:
Category[({type TypeConstructor[FirstParam,
SecondParam] = Kleisli[MonadParam, FirstParam,
SecondParam])#TypeConstructor] = new Category[({type
TypeConstructor[FirstParam, SecondParam] = Kleisli[MonadParam,
FirstParam, SecondParam]})#Constructor] = {
def identity[ForType] = kleisli(value => value.pure)
def compose[Input, InputOutput, Output](secondFunction:
Kleisli[MonadParam, InputOutput, Output], firstFunction:
Kleisli[MonadParam, Input, InputOutput]) = kleisliCompose(firstFunction,
secondFunction)
}
// This is the original.
implicit def KleisliCategory[M[_]: Monad]: Category[({type λ[α, β]=Kleisli[M, α, β]})#λ] = new Category[({type λ[α, β]=Kleisli[M, α, β]})#λ] {
def id[A] = ☆(_ η)
def compose[X, Y, Z](f: Kleisli[M, Y, Z], g: Kleisli[M, X, Y]) = f <=< g
}
// Some things I prefer about the longer version: the unicode star is
// stupid, as is using an eta for the `pure` natural transformation.
// The ({type λ[α, β]=...})#λ nonsense is an unfortunate consequence of
// the Scala language. Nobody really likes that, but there's not a whole
// lot that can be done to improve it.
@jonsterling
Copy link
Author

By the way, if this were written in a better language, most of this nonsense would be unnecessary. Imagine the following (basically, if it were Haskell):

instance Monad m => Category (Kleisli m) where
    identity = kleisli . return
    compose = kleisliCompose

That's basically the same code, but in a language with a sane syntax.

@jonsterling
Copy link
Author

Or if you want to keep the same explicit dictionary style:

kleisliCategory = { 
    identity = kleisli . return,
    compose = kleisliCompose
}

If Haskell had implicit parameters, that would be a closer approximation of the Scala approach to type classes (which is strictly more powerful than Haskell's). Note that with good type inference, we don't need all the lambdas and points (variables). The reason Scalaz code is ugly as hell is that Scala itself is ugly as hell. Trying to write Haskell in Scala leads to pain; many find it useful, though, which is why we have things like Scalaz.

@harms
Copy link

harms commented Aug 28, 2012

My sense is that much of the value of scalaz is that it accomplishes rather cumbersome definitions for meanings that are more-or-less readily available in languages like Haskell.

I'd find it entertaining to see the same thing coded in Java, but much of the entertainment value would lie in seeing how much of Scala has to be implemented in order to work at this level of abstraction. There would be a lot more code to read, and I imagine it would be less "easy to read" as a result. The Haskell version is easier to read precisely because it expresses the same concept in fewer pieces.

The two Scala versions, above, hardly differ in token count, nor in structure. The version with shorter names better exposes that structure.

@jonsterling
Copy link
Author

Well put.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment