Я сейчас экспериментирую с F #.Статьи, найденные в Интернете, полезны, но, как программист на C #, я иногда сталкиваюсь с ситуациями, когда думаю, что моё решение поможет, но оно не помогло или помогло частично.
Так что мое отсутствие знаний F #(и, скорее всего, то, как работает компилятор), вероятно, является причиной, по которой я иногда просто поражен.
Например, я написал программу на C # для определения идеальных чисел.Он использует известную форму доказательства Евклида, что идеальное число может быть сформировано из простого Мерсенна 2p-1 (2p-1) (где 2p-1 - простое число, а p обозначено как степень).
Поскольку с помощью F # утверждается, что для вычисления степени можно использовать «**», но используются числа с плавающей запятой, я попытался создать простую функцию с оператором побитового сдвига (<<<) (обратите внимание, что я редактировалэтот код указывает на необходимость): </p>
let PowBitShift (y:int32) = 1 <<< y;;
Однако при запуске теста и поиске улучшений производительности я также попробовал форму, которую я помню, используя Miranda (также функциональный язык программирования),который использует рекурсию и сопоставление с образцом для расчета мощности.Основное преимущество заключается в том, что я могу использовать переменную y в качестве 64-разрядного целого числа, что невозможно при использовании стандартного оператора битового сдвига.
let rec Pow (x : int64) (y : int64) =
match y with
| 0L -> 1L
| y -> x * Pow x (y - 1L);;
Оказывается, эта функция на самом деле быстрее, но я не могу (пока) понять причину этого.Возможно, это менее интеллектуальный вопрос, но мне все еще любопытно.
Тогда возникает второй вопрос: при вычислении совершенных чисел вы сталкиваетесь с тем фактом, что int64 не может отобразить пересечение больших чисел после нахождения9-й совершенный номер (который образован из силы 31).Я пытаюсь выяснить, можно ли тогда использовать объект BigInteger (или тип bigint), но здесь мои знания F # немного меня блокируют.Можно ли создать функцию power, которая принимает оба аргумента как bigints?
В настоящее время у меня есть это:
let rec PowBigInt (x : bigint) (y : bigint) =
match y with
| bigint.Zero -> 1I
| y -> x * Pow x (y - 1I);;
Но выдает ошибку, что bigint.Zero не определен.Так что я тоже что-то не так делаю.0 Я не принят в качестве замены, так как он выдает эту ошибку:
Non-primitive numeric literal constants cannot be used in pattern matches because they
can be mapped to multiple different types through the use of a NumericLiteral module.
Consider using replacing with a variable, and use 'when <variable> = <constant>' at the
end of the match clause.
Но сопоставитель шаблонов не может использовать оператор «когда».Есть ли другое решение для этого?
Заранее спасибо, и, пожалуйста, прости мой длинный пост.Я только пытаюсь выразить свои «вызовы» как можно яснее.