Out of curiosity, I'm porting the Haskell exercises of Programming in Haskell by Graham Hutton to Standard ML. At the beginning everything seemed pretty similar until I reached list comprehensions:
(x,y,z)of positive integers is called pythagorean if
x2 + y2 = z2. Using a list comprehension, define a function
pyths ∷ Int → [(Int,Int,Int)]that maps an integer
nto all such triples with components in
The Haskell version is pretty simple:
pyths ∷ Int → [(Int, Int, Int)] pyths n = [(x, y, z) | x ← [1..n], y ← [1..n], z ← [1..n], x^2 + y^2 == z^2]
My Standard ML attempt, not so much:
(* No list comprehensions in SML so we need a helper function *) val generateIntsUpTo = fn n => let val rec helper = fn current => fn xs => if current <= n (* then current :: helper (current + 1) xs *) then helper (current + 1) (current :: xs) else xs in rev (helper 1 ) end (* Now we can find the pyths *) val pyths = fn n => let val numbers = generateIntsUpTo n in foldr (fn (x, acc) => foldr (fn (y, acc) => foldr (fn (z, acc) => if x * x + y * y = z * z then (x, y, z) :: acc else acc ) acc numbers ) acc numbers )  numbers end
The first thing that I don't like is the call to
rev at the end of
generateIntsUpTo but I did it to accomplish a tail recursive function. Commented out is the line that lets me avoid the reversion of the list but then it's not tail recursive.
Besides that, there's the three nested
foldr calls. I have been thinking of writing my own recursive functions, but I wanted to do this with the minimum amount of custom code.