Я работаю над базовым движком 2D CAD, и оператор трубопровода значительно улучшил мой код. В основном несколько функций начинаются с точки (x, y) в пространстве и вычисляют конечную позицию после ряда операций перемещения:
let finalPosition =
startingPosition
|> moveByLengthAndAngle x1 a1
|> moveByXandY x2 y2
|> moveByXandAngle x3 a3
|> moveByLengthAndAngle x4 a4
// etc...
Это невероятно легко читать, и я бы хотел, чтобы это так и оставалось. Различные x1, a1 и т. Д., Очевидно, имеют значение в реальном коде.
Теперь новое требование - ввести обработку исключений. Недостаточно больших попыток во всей цепочке операций, потому что я хотел бы знать, какая строка вызвала исключение. Мне нужно знать, какой аргумент недопустим, чтобы пользователь знал, какой параметр необходимо изменить.
Например, если первая строка (moveByLengthAndAngle x1 a1) вызывает исключение, я хотел бы сказать что-то вроде «Эй, -90 - недопустимое значение для a1! A1 должно быть между 45 и 90!». Учитывая, что в последовательности можно использовать много операций одного и того же типа, недостаточно определить разные типы исключений для каждой операции (в этом примере я не смог бы определить, была ли ошибка первым или последним перемещением).
Очевидное решение состоит в том, чтобы разбить цепочку на отдельные операторы let, каждое в пределах соответствующей попытки / с. Это, однако, сделало бы мой красивый и читаемый код немного грязным, уже не так читаемым.
Есть ли способ удовлетворить это требование, не жертвуя удобочитаемостью и элегантностью текущего кода?
(примечание. Прямо сейчас каждая функция moveBy вызывает исключение в случае ошибок, но я могу свободно изменять, например, возвращать опцию, больший кортеж или что-нибудь еще, если необходимо).