Reputation: 924
I'm another beginner attempting to complete a MOOC course with an SML element. I want to produce a function that takes a list, and produces a second list with the elements summed.
if done correctly, this function will transform
before_reaching_sum_test([1,2,3,4,5,6,7,8,9]);
to the following list
[1,3,6,10,16,23,31,40]
This is what I have so far, but I'm pretty sure I'm going about it incorrectly.
fun before_reaching_sum_test(ints: int list) =
if null (tl ints)
then []
else (hd ints + hd (before_reaching_sum_test(tl ints)))::(before_reaching_sum_test(tl ints))
I know that this will leave off the last element of the initial list. but will something like this work?
Upvotes: 0
Views: 596
Reputation: 5944
Your problem is with this line hd (before_reaching_sum_test(tl ints))
, it keeps calling recursively on the tail of the list, until it will return the empty list, which you then tries to take the head of. Thus the empty exception is raised.
It can actually be created very simply
fun before_reaching_sum_test (x::y::xs) = x :: before_reaching_sum_test(x+y::xs)
| before_reaching_sum_test x = x
by "pushing the previous number ahead" and calculating a running sum.
Update
Brace for impact
fun before_reaching_sum_test xs =
if null xs then xs (* empty list *)
else if null (tl xs) then xs (* one element list *)
else (* Two or more elements in the list *)
let
val x = hd xs
val y = hd (tl xs)
in
x :: before_reaching_sum_test (x+y :: tl (tl xs))
end
This actually serves as a nice example of why pattern matching is a nice thing to have.
Upvotes: 2