Понимание ошибок ограничения значения F#

В Java эти реальные классы вся реализация интерфейс CharSequence:

CharBuffer, Строка, StringBuffer, StringBuilder

Эти реальные классы не имеют общего родительского класса кроме Объекта, таким образом, нет ничего, что связывает их кроме факта, каждый из них имеет некоторое отношение к массивам символов, представляя такой, или управляя таким. Например, символы Строки не могут быть изменены, как только Строковый объект инстанцируют, тогда как символы StringBuffer или StringBuilder могут быть отредактированы.

все же каждый из этих классов способен к подходили реализации методов интерфейса CharSequence:

char charAt(int index)
int length()
CharSequence subSequence(int start, int end)
String toString()

В некоторых случаях классы Библиотеки классов Java, которые раньше принимали Строку, были пересмотрены, чтобы теперь принять интерфейс CharSequence. Таким образом, если у Вас есть экземпляр StringBuilder, вместо того, чтобы извлечь Строковый объект (что означает инстанцировать нового экземпляра объекта), может вместо этого просто передать сам StringBuilder, поскольку это реализует интерфейс CharSequence.

интерфейс Appendable, что некоторая реализация классов имеет почти такой же вид преимущества для любой ситуации, где символы могут быть добавлены к экземпляру базового экземпляра объекта реального класса. Все эти реальные классы реализуют интерфейс Appendable:

BufferedWriter, CharArrayWriter, CharBuffer, FileWriter, FilterWriter, LogStream, OutputStreamWriter, PipedWriter, PrintStream, PrintWriter, StringBuffer, StringBuilder, StringWriter, Писатель

20
задан Community 23 May 2017 в 11:55
поделиться

3 ответа

РЕДАКТИРОВАТЬ

Лучшая / свежая информация здесь: Сохранение частично примененных общих функций

(оригинал ниже)

Я думаю, что здесь прагматично не пытаться понять это слишком глубоко, а лучше знать пару общих стратегий, чтобы пройти через виртуальную реальность и продолжить свою работу. Это что-то вроде ответа «отговорки», но я не уверен, что имеет смысл тратить время на понимание внутренних особенностей системы типов F # (которая продолжает незначительно меняться от выпуска к выпуску).

Я бы отстаивал две основные стратегии: Во-первых, если вы определяете значение с помощью типа функции (введите со стрелкой '->'), убедитесь, что это синтаксическая функция, выполнив eta-преобразование :

// function that looks like a value, problem
let tupleList = List.map (fun x -> x,x)
// make it a syntactic function by adding argument to both sides
let tupleList l = List.map (fun x -> x,x) l

Во-вторых, если вы все еще сталкиваются с проблемами VR / обобщающими, затем укажите всю сигнатуру типа, чтобы сказать то, что вы хотите (а затем «отступите», как позволяет F #):

// below has a problem...
let toleq (e:float<_>) a b = (abs ( a - b ) ) < e
// so be fully explicit, get it working...
let toleq<[<Measure>]'u> (e:float<'u>) (a:float<'u>) (b:float<'u>) : bool = 
    (abs ( a - b ) ) < e
// then can experiment with removing annotations one-by-one...
let toleq<[<Measure>]'u> e (a:float<'u>) b = (abs ( a - b ) ) < e

Я думаю, что эти две стратегии - лучший прагматический совет. Тем не менее, вот моя попытка ответить на ваши конкретные вопросы.

  1. Я не знаю.

  2. '>' - это полностью универсальная функция ('a ->' a -> bool), которая работает для всех типов, и таким образом is_bigger обобщает. С другой стороны, «+» - это «встроенная» функция, которая работает с несколькими примитивными типами и определенным классом других типов; он может быть обобщен только внутри других «встроенных» функций, в противном случае он должен быть привязан к определенному типу (или по умолчанию будет использоваться значение «int»). («Встроенный» метод специального полиморфизма - это то, как математические операторы в F # преодолевают недостаток «классов типов». )

  3. Это проблема «синтаксической функции», которую я обсуждал выше; 'давайте скомпилируем в поля / свойства, которые, в отличие от функций, не могут быть общими. Итак, если вы хотите, чтобы он был универсальным, сделайте его функцией. (См. Также этот вопрос для другого исключения из этого правила.)

18
ответ дан 30 November 2019 в 00:55
поделиться

Никто, включая людей из команды F #, не знает сколько-нибудь значимого ответа на этот вопрос.

Система вывода типа F # в точности похожа на грамматику VB6 в том смысле, что компилятор определяет истину.

К сожалению, но это правда.

2
ответ дан 30 November 2019 в 00:55
поделиться

Ограничение значений было введено для решения некоторых проблем с полиморфизмом при наличии побочных эффектов. F # наследует это от OCaml, и я считаю, что ограничение значений существует во всех вариантах ML. Вот несколько дополнительных ссылок , которые вы можете прочитать, помимо ссылок, которые вы цитировали. Поскольку Haskell чист, он не подвергается этому ограничению.

Что касается ваших вопросов, я думаю, что вопрос 3 действительно связан с ограничением значений, а первые два - нет.

5
ответ дан 30 November 2019 в 00:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: