import Data.List (nub, permutations, sort)
ternas :: [(Integer,Integer,Integer)]
ternas = concatMap ternasSuma [3..]
-- (ternasSuma n) es la lista de las ternas de enteros positivos cuya
-- suma es n ordenadas lexicográficamte. Por ejemplo,
-- λ> ternasSuma 3
-- [(1,1,1)]
-- λ> ternasSuma 4
-- [(1,1,2),(1,2,1),(2,1,1)]
-- λ> ternasSuma 5
-- [(1,1,3),(1,2,2),(1,3,1),(2,1,2),(2,2,1),(3,1,1)]
-- λ> ternasSuma 6
-- [(1,1,4),(1,2,3),(1,3,2),(1,4,1),(2,1,3),(2,2,2),(2,3,1),(3,1,2),(3,2,1),(4,1,1)]
ternasSuma :: Integer -> [(Integer,Integer,Integer)]
ternasSuma n =
sort (concatMap permutaciones [(a,b,c) | a <- [1..n]
, b <- [a..n]
, let c = n-a-b
, b <= c])
-- (permutaciones t) es la lista de las permutaciones de la terna t. Por ejemplo,
-- λ> permutaciones (1,2,3)
-- [(1,2,3),(2,1,3),(3,2,1),(2,3,1),(3,1,2),(1,3,2)]
-- λ> permutaciones (1,1,2)
-- [(1,1,2),(2,1,1),(1,2,1)]
-- λ> permutaciones (1,1,1)
-- [(1,1,1)]
permutaciones :: (Integer,Integer,Integer) -> [(Integer,Integer,Integer)]
permutaciones (a,b,c) =
nub [(x,y,z) | [x,y,z] <- permutations [a,b,c]] |