Is this a reasonable Scala monad? I found myself writing code of the form...

val foo : Foo = ???

val step1 : Foo = {
  if ( someCharacteristic( foo ) )
    someTransformation( foo )
  else
    foo
}
val step2 : Foo = {
  if ( otherCharacteristic( foo ) )
    otherTransformation( foo )
  else
    foo
}

val result = step2;


That seemed awkward, and it seemed like this sort of ugly stepwise processing could be monadified. I've used but not written Scala monads; I thought I'd give it a shot. What I have seems to work, but I found proving the monad laws surprisingly challenging. I'm not sure I've got a valid monad, and wonder whether there is some subtle problem that would bite me someday if I haven't. FWIW, here's the code, any comments would be very welcome.

package dumbmonad;

import scala.language.implicitConversions;

object If {
  implicit def unwrap[T]( ift : If[T] ) = ift.value;

  def evaluate[T]( ift : If[T] ) : T = if ( ift.condition( ift.value ) ) ift.transformation( ift.value ) else ift.value;

  def flatten[T]( outer : If[If[T]] ) : If[T] = evaluate( outer );

  def apply[T]( value : T ) : If[T] = apply( value, _ =&gt; false, identity );
}

case class If[T]( val value : T, val condition : (T)=&gt;Boolean, val transformation : (T)=&gt;T ) {

  lazy val evaluate : T = If.evaluate( this );

  def map[S]( f : (T) =&gt; S ) : If[S] = If( f( this.evaluate ) )
  def flatMap[S]( f : (T) =&gt; If[S] ) : If[S] = If.flatten( this.map( f ) )
}


I use it like this:

import dumbmonad._;
import dumbmonad.If._;

val foo : Foo = ???

for {
  a &lt;- If( foo, someCharacteristic, someTransformation )
  b &lt;- If( a, otherCharacteristic, otherTransformation )
} yield b;

val result : Foo = b; // implicit call to If.unwrap( ... )


Is this terrible?
What you are describing are simply functions.

To take a related example from mathematics, 

          /   x, if x &gt;= 0
abs(x) =  |
          \  -x, otherwise


And you are just composing functions: f(g(x)).

You can somewhat make the correspondence to monads, but it is a bit of a stretch.  I think it is more that monads are extensions of functions rather than the other way around.

flatMap would be the composition operator: o  , ie (f o g)(x) = f(g(x)).  And unit would just be the identity operation: I(x) = x.

The three monad laws:


Associativity: f o (g o h) = (f o g) o h
Left unit: I o f = f
Right unit: f o I = f


So instead of defining your If class, you can just stick to def, the usual function definition.  Functional programming!!!  In your case you can compose all your functions in any order since they always input/output Foo type.  You can compose functions in Scala with val h = f _ compose h _, or using andThen.