Проблема заключается в этой строке
produceResult (xs, ys) (fun c -> (code,Math.Abs(rate-rate2))::(k c))
Здесь вы вызываете продолжение, но этот вызов не является хвостовым, потому что вам все еще нужно использовать минусы (code, Math.Abs (rate-rate2)) для результата (k c)
Я думаю, вы можете построить список результатов изнутри и просто поменять местами окончательный результат:
let identifiedDifference list1 list2 =
let rec produceResult (l1, l2) k =
match l1,l2 with
| [],[]
| _,[]
| [],_ -> k []
| (code,rate:float)::xs, (code2,rate2)::ys ->
if code = code2
then
produceResult (xs, ys) (fun c -> k((code,Math.Abs(rate-rate2))::c))
elif code > code2
then produceResult (l1, ys) k
else produceResult (xs, l2) k
produceResult (list1, list2) List.rev
EDIT:
после второго взгляда я думаю, что CPS здесь не нужен, и использование аккумулятора должно помочь:
let identifiedDifference list1 list2 =
let rec run l1 l2 acc =
match l1, l2 with
| [], _ | _, [] -> List.rev acc
| (code1, rate1 : float)::xs, (code2, rate2)::ys ->
if code1 = code2 then
run xs ys ((code1, abs (rate1 - rate2))::acc)
elif code1 > code2 then
run l1 ys acc
else
run xs l2 acc
run list1 list2 []