Find Pythagorean Triple with Perimeter == 24 Learn You a Haskell gives this exercise:


  Here's a problem that combines tuples and list comprehensions: which
  right triangle that has integers for all sides and all sides equal to
  or smaller than 10 has a perimeter of 24? First, let's try generating
  all triangles with sides equal to or smaller than 10:


Here's my solution in Scala. Note that I'm ignoring the right triangle part.

val a = List.range(1,11)
val b = List.range(1,11)
val c = List.range(1,11)

def sumsEqualsTo24(x: Int, y: Int, z: Int): Option[(Int, Int, Int)] = 
                           if(x + y + z == 24) Some( (x,y,z) ) else None

def pythagTriple(x: Int, y: Int, z: Int): Option[(Int, Int, Int)] = { 
                             if( Math.pow(x, 2) + Math.pow(y, 2) == Math.pow(z, 2) )
                                  Some( (x,y,z) ) 
                             else None
}


Using flatMap

val xs: List[(Int, Int, Int)] = a.flatMap(x =&gt; 
                                 b.flatMap(y =&gt; 
                                  c.flatMap(z =&gt; sumsEqualsTo24(x, y, z) ) ) )                                   

val ys: List[(Int, Int, Int)] = xs.flatMap{a =&gt; pythagTriple(a._1, a._2, a._3)}


Using for-comprehension

for {
  a &lt;- List.range(1, 11)
  b &lt;- List.range(1, 11)
  c &lt;- List.range(1, 11) 
  xs &lt;- sumsEqualsTo24(a,b,c)
  _ &lt;- pythagTriplebar(xs._1, xs._2, xs._3)
} yield (a,b,c)


Could you please critique my code?
There is no need for Lists a,b, and c, only one of them is needed.

So the flatmap could just use a three times: 

a.flatMap(x =&gt; 
  a.flatMap(y =&gt; 
    a.flatMap(z =&gt; sumsEqualsTo24(x, y, z))))


For comprehensions can use extractors as you would in pattern matching or declaring a val.
You may find this more readable:

  ...
  c &lt;- List.range(1, 11) 
  (x,y,z) &lt;- sumsEqualsTo24(a,b,c)
  _ &lt;- pythagTriplebar(x,y,z)
} yield (a,b,c)


Likewise you can have

val ys = xs.flatMap{case (x,y,z) =&gt; pythagTriple(x,y,z)}