Вместо того, чтобы использовать папку за пределами вашего проекта, скопируйте все необходимые JAR-файлы в папку lib/
внутри вашего проекта.
Теперь вы можете выбрать все файлы JAR в этой папке, щелкните правой кнопкой мыши -> Путь сборки -> Добавить в путь сборки.
Кроме того, вы можете определить «Пользовательскую библиотеку», которая содержит все JAR-файлы, и добавить этот единственный элемент в путь сборки вашего проекта.
Но лучшее решение IMO, это использовать Maven для этого. Получите плагин M2E для Eclipse и преобразуйте ваш проект в проект Maven. Теперь вы можете использовать «Добавить зависимость», чтобы добавить миллионы других проектов (включая все, что им нужно ) в ваш проект. Maven будет загружать и управлять зависимостями для вас.
Я думаю, что это в основном вопрос ситуации.
Рассмотрите пути. Стандартная прелюдия имеет «type FilePath = String», потому что для удобства вы хотите иметь доступ ко всем операциям со строками и списками. Если бы у вас был «newtype FilePath = FilePath String», тогда вам понадобились бы filePathLength, filePathMap и так далее, иначе вы бы всегда использовали функции преобразования.
С другой стороны, рассмотрите SQL-запросы. SQL-инъекция является распространенной дырой в безопасности, поэтому имеет смысл иметь что-то вроде
newtype Query = Query String
, а затем добавлять дополнительные функции, которые будут преобразовывать строку в запрос (или фрагмент запроса) путем экранирования символов кавычек или заполнения пробелов в шаблоне в так же. Так ты сможешь '
Для простых объявлений X = Y
, тип
является документацией; newtype
- проверка типа; вот почему newtype
сравнивается с данными
.
Я довольно часто использую newtype
только для той цели, которую вы описываете: обеспечение того, что что-то хранится (и часто манипулируют) так же, как другой тип не путают с чем-то другим. Таким образом, он работает как чуть более эффективное объявление данных
; нет особой причины выбирать одно перед другим. Обратите внимание, что с расширением GHC GeneralizedNewtypeDeriving
для любого из них вы можете автоматически создавать классы, такие как Num
, позволяя суммировать и вычитать ваши температуры или иены, как вы можете, с помощью Int
s или того, что лежит под ними. Однако с этим нужно быть немного осторожнее; обычно температуру не умножают на другую!
Чтобы понять, как часто эти вещи используются, в одном достаточно большом проекте, над которым я сейчас работаю, у меня есть около 122 применений данных
, 39 применений newtype
и 96 применений типа
.
Но соотношение, что касается «простых» типов, немного ближе, чем демонстрирует , поскольку 32 из этих 96 использований типа
на самом деле являются псевдонимами для типов функций, например
type PlotDataGen t = PlotSeries t -> [String]
. Здесь вы заметите две дополнительные сложности: во-первых, это фактически тип функции, не просто псевдоним X = Y
, и во-вторых, он параметризован: PlotDataGen
- это конструктор типа, который я применяю к другому типу для создания нового типа, например PlotDataGen (Int, Double)
. Когда вы начинаете делать такие вещи, type
уже не просто документация, а фактически функция, хотя на уровне типа, а не на уровне данных.
newtype
иногда используется там, где type
не может быть, например, когда необходимо определение рекурсивного типа, но я считаю, что это достаточно редко. Похоже, что, по крайней мере, в этом конкретном проекте около 40% моих "примитивных" определений типов относятся к newtype
s, а 60% - к type
s. Некоторые из определений newtype
раньше были типами,
Я думаю, что довольно часто использовать newtype
для различения типов. Во многих случаях это связано с тем, что вы хотите предоставить экземпляры классов разных типов или скрыть реализации, но простое желание защитить от случайных преобразований также является очевидной причиной для этого.