Скрытые возможности F #

Измените эту строку:

t = timeit.Timer("foo()")

К этому:

t = timeit.Timer("foo()", "from __main__ import foo")

Проверьте ссылку, которую вы указали в самом низу.

] Чтобы предоставить модулю timeit доступ к определенным вами функциям, вы можете передать параметр настройки, который содержит оператор импорта:

Я только что протестировал его на своей машине и работал с изменениями.

23
задан 6 revs, 2 users 57% 23 May 2017 в 11:47
поделиться

10 ответов

Автоматически сгенерированные функции сравнения для алгебраических типов данных (на основе лексикографического упорядочивания) являются хорошей функцией, которая относительно неизвестна; см.

http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!548.entry

для примера.

7
ответ дан Brian 23 May 2017 в 11:47
поделиться

Да, F# не имеет никаких 'скрытых' функций, но он уверенный действительно имеет много силы, упакованной на простой язык. Менее известная функция языка, то, где Вы можете в основном включать утку, вводящую несмотря на факт, F# статически вводится.

6
ответ дан Chris Smith 23 May 2017 в 11:47
поделиться

Нет никаких скрытых функций, потому что F# находится в режиме проектирования. Все, что мы имеем, являются Предварительным техническим обзором, который изменяет каждое двухмесячное.

см. http://research.microsoft.com/fsharp/

1
ответ дан ChaosSpeeder 23 May 2017 в 11:47
поделиться

Использование F # в качестве служебного языка сценариев может быть недооценено. Энтузиасты F # склонны быть квантами. Иногда для резервного копирования файлов MP3 (или десятков серверов баз данных) требуется что-то более надежное, чем пакетное. Я охотился на современную замену jscript / vbscript. В последнее время я использовал IronPython, но F # может быть более полным, а взаимодействие с .NET менее громоздким.

Мне нравятся каррированные функции для развлечения. Покажите каррированную функцию чистой процедурной программе / программе ООП как минимум для трех WTF. Однако начинать с этого - плохой способ конвертировать F # :)

3
ответ дан 29 November 2019 в 00:43
поделиться

См. Этот вопрос

Оператор F # "?"

для получения информации об операторе вопросительного знака и о том, как он обеспечивает базовый языковой механизм для создания функции, подобной 'динамической' в C #.

6
ответ дан 29 November 2019 в 00:43
поделиться

Пользовательские числовые литералы могут быть определены путем предоставления модуля, имя которого начинается с NumericLiteral и который определяет определенные методы ( FromZero , FromOne и т. Д.).

В частности, вы можете использовать это для обеспечения более удобочитаемого синтаксиса для вызова LanguagePrimitives.GenericZero и LanguagePrimitives.GenericOne :

module NumericLiteralG = begin
  let inline FromZero() = LanguagePrimitives.GenericZero
  let inline FromOne() = LanguagePrimitives.GenericOne
end

let inline genericFactorial n =
  let rec fact n = if (n = 0G) then 1G else n * (fact (n - 1G))
  fact n

let flt = genericFactorial 30.
let bigI = genericFactorial 30I
29
ответ дан 29 November 2019 в 00:43
поделиться

F # имеет малоиспользуемую функцию, называемую «файлы сигнатур». У вас может быть большой файл реализации, полный общедоступных типов / методов / модулей / функций, но тогда вы можете скрыть и выборочно предоставить эту функциональность для продолжения программы через файл подписи . То есть файл подписи действует как своего рода экран / фильтр, который позволяет вам делать объекты «общедоступными для этого файла», но «закрытыми для остальной части программы».

Я считаю, что это довольно убийственная функция в платформа .Net, потому что единственный другой / предыдущий инструмент, который у вас есть для такого рода инкапсуляции, - это сборки. Если у вас есть небольшой компонент с несколькими связанными типами, которые хотят видеть внутренние детали друг друга, но не Не хочу, чтобы все эти типы были общедоступными для всех , что вы можете сделать? Что ж, вы можете сделать две вещи:

  1. Вы можете поместить этот компонент в отдельную сборку и сделать элементы, которые разделяют эти типы, «внутренними», а узкую часть, которую вы хотите, чтобы все остальные видели, - «общедоступной», или
  2. Вы просто помечаете внутренний материал как «внутренний», но вы оставляете эти типы в своей гигантской сборке и просто надеетесь, что весь другой код в сборке решит не вызывать те члены, которые были помечены как «внутренние», потому что еще один тип

По моему опыту, в крупных программных проектах каждый всегда делает №2, потому что №1 не запускается по разным причинам (люди не хотят 50 небольших сборок, они хотят 1 или 2 или 3 больших сборки, по другим, возможно, веским причинам, не связанным с точкой инкапсуляции, которую я поднимаю (в сторону: все упоминают ILMerge, но никто не использует его)).

Итак, вы выбрали вариант №2. Затем, год спустя, вы, наконец, решаете рефакторинг этого компонента и обнаруживаете, что за последний год 17 других мест теперь вызывают этот `` внутренний '' метод, который на самом деле предназначен только для вызова этого другого типа, что делает его действительно трудно исключить этот момент, потому что теперь все зависят от этих деталей реализации. Облом.

Дело в том, что нет хорошего способа создать область / границу инкапсуляции внутри сборки в .Net. Часто «внутреннее» слишком велико, а «частное» слишком мало

... до F #. С помощью файлов подписи F # вы можете создать область инкапсуляции «этого файла исходного кода» пометив кучу материалов как общедоступных в файле реализации, чтобы весь остальной код в файле мог видеть его и участвовать в нем, но затем использовать файл подписи, чтобы скрыть все детали, ожидая узкого общедоступного интерфейса, который компонент предоставляет Остальной мир. Это рада. Определите три тесно связанных типа в одном файле, позвольте им видеть детали реализации друг друга, но открывайте для всех только действительно общедоступный материал. Win!

Файлы подписей, возможно, не являются идеальной функцией для границ инкапсуляции внутри сборки, но они являются единственной такой функцией, которую я знаю, и поэтому я цепляюсь за них как спасательный плот в океане

TL; DR

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

10
ответ дан 29 November 2019 в 00:43
поделиться

Встроенные операторы для универсальных типов могут иметь разные общие ограничения:

type 'a Wrapper = Wrapper of 'a with
  static member inline (+)(Wrapper(a),Wrapper(b)) = Wrapper(a + b)
  static member inline Exp(Wrapper(a)) = Wrapper(exp a)

let objWrapper = Wrapper(obj())
let intWrapper = (Wrapper 1) + (Wrapper 2)
let fltWrapper = exp (Wrapper 1.0)

(* won''t compile *)
let _ = exp (Wrapper 1)
2
ответ дан 29 November 2019 в 00:43
поделиться

Передача - warnon: 1182 компилятору включает предупреждения о неиспользуемых переменных; имена переменных, начинающиеся с подчеркивания, не имеют иммунитета.

8
ответ дан 29 November 2019 в 00:43
поделиться

Не совсем скрыто , но как человек, не занимающийся машинным обучением, я довольно долго ускользал от меня:

Сопоставление с образцом может разложить произвольно глубоко на структуры данных.

Вот [невероятно произвольный] пример вложенного кортежа; это работает со списками, объединениями или любыми комбинациями вложенных значений:

let listEven =
  "Manipulating strings can be intriguing using F#".Split ' '
  |> List.ofArray
  |> List.map (fun x -> (x.Length % 2 = 0, x.Contains "i"), x)
  |> List.choose 
     ( function (true, true), s -> Some s 
              | _, "F#"         -> Some "language" 
              | _               -> None ) 
5
ответ дан 29 November 2019 в 00:43
поделиться