Ответ 1
Я бы посоветовал против неумеренного использования полиморфных вариантов. Они выглядят хорошо на бумаге, но более гибкий вывод и подтипирование придут, чтобы укусить вас в любое время. Когда я использую полиморфные варианты, я стараюсь, чтобы каждое использование аннотировалось с помощью выражения с выражением строгого ограничения.
Я бы посоветовал вернуться и изменить старый код, как это кажется естественным. Если вы написали свой код с учетом расширяемости и, в частности, избегали _
-patterns по типу bool2
, тогда компилятор предупредит вас о любом месте, где сделано предположение о наличии только двух конструкторов. Эта компиляторная обратная связь по модификации типов очень полезна, так как это механическая помощь, чтобы сделать вашу программу правильной.
Этот способ делать вещи имеет, конечно, некоторые недостатки. Один из них заключается в том, что изменение определения типа, тогда изменение каждого варианта использования может не сработать с вашей обычной практикой компиляции: если вы сделаете это на большой базе кода, у вас будет большое количество вещей, которые нужно выполнить перед компиляцией вашего проекта (и, следовательно, можно протестировать). Вы можете разделить свою модификацию на несколько патчей на свою систему контроля версий, но это означает, что некоторые посреднические совершенные состояния не компилируются, что не очень приятно. Другая возможность заключается в том, чтобы изменить это место только для добавления сбоя во время выполнения (| Third_one -> assert false
), тогда у вас есть компилируемый код, и вы можете исправить эти сбои, как это происходит во время выполнения во время тестирования приложения. Но я по-прежнему думаю, что статическая компиляция обратной связи - хорошая помощь для обслуживания кода.
Существует также возможность обертывания алгебраического типа данных в "расширенном алгебраическом типе данных" type bool3 = New | Old of bool2
, который обсуждается в ссылке, которую вы даете в качестве комментария ответа Мартина. Это может быть хорошим способом перехода от одного типа данных к другому без нарушения компиляции, но в долгосрочной перспективе это болезненно, особенно если вы складываете больше этих расширений друг на друга.
Конечно, то, что действительно понадобилось бы в некоторых ситуациях, было бы способом расширить тип данных путем добавления кода, а не модификации кода, таким образом, который является статически безопасным, легче компилировать, запускать и тестировать, а также эффективный во время выполнения. Это пример Проблема выражения, из которых они представляют собой различные решения, одним из которых являются полиморфные варианты. Но в общем случае вам не нужна дополнительная гибкость только для добавления кода, и это не стоит дополнительной сложности соответствующих языковых функций, поэтому я бы посоветовал придерживаться простых старых вариантов, если это явно не огромная получить по-другому.
PS: в отношении полиморфных вариантов и их связи с проблемой выражения обязательная статья Повторное использование кода через полиморфные варианты Жака Гаррига.