Это беззастенчивая попытка аналогичного вопроса C#.
Итак, какие ваши любимые скрытые (или нет) функции F#?
Большинство функций, которые я использовал до сих пор, не совсем скрыты, но были довольно освежающими. Например, насколько тривиально перегружать операторы по сравнению, скажем, с C# или VB.NET.
И Async<T> помог мне избавиться от действительно уродливого кода.
Я все еще новичок в этом языке, поэтому было бы здорово узнать, какие еще функции используются в дикой природе.





Здесь нет скрытых функций, потому что F# находится в режиме разработки. Все, что у нас есть, - это предварительный технический обзор, который меняется каждые два месяца.
см. http://research.microsoft.com/fsharp/
Да, F# не имеет каких-либо «скрытых» функций, но, несомненно, в нем есть много возможностей, заключенных в простом языке. Менее известная особенность языка - это то, где вы можете в основном включить утиный ввод, несмотря на то, что F# статически типизирован.
Автоматически сгенерированные функции сравнения для алгебраических типов данных (основанные на лексикографическом порядке) - приятная особенность, которая относительно неизвестна; видеть
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!548.entry
для примера.
Использование F# в качестве служебного языка сценариев может быть недооценено. Энтузиасты F# склонны быть квантами. Иногда для резервного копирования файлов MP3 (или десятков серверов баз данных) требуется что-то более надежное, чем пакетное. Я искал современную замену jscript / vbscript. В последнее время я использовал IronPython, но F# может быть более полным, а взаимодействие с .NET менее громоздким.
Мне нравится каррированные функции для развлечения. Покажите каррированную функцию чистой процедурной программе / программе ООП как минимум для трех WTF. Однако начинать с этого - плохой способ конвертировать F# :)
Мне нравится использовать FSI для небольших скриптов, и я действительно использовал некоторые файлы .fsx для разных вещей. Однако, по крайней мере, по моему опыту, время запуска, необходимое для файлов .fsx, слишком велико для сценариев общего назначения. Я по-прежнему предпочитаю командные файлы и сценарии Perl для написания сценариев.
Попробуйте PowerShell и не пожалеете :)
Посмотреть этот вопрос
для получения информации об операторе вопросительного знака и о том, как он обеспечивает базовый языковой механизм для создания функции, подобной «динамической» в C#.
В F# есть малоиспользуемая функция, которая называется «файлы сигнатур». У вас может быть большой файл реализации, полный типов / методов / модулей / функций общественный, но затем вы можете прятать и выборочно выставлять напоказ этой функциональности для продолжения программы через файл сигнатуры. То есть файл подписи действует как своего рода экран / фильтр, который позволяет вам делать объекты «общедоступными для этого файла», но «закрытыми для остальной части программы».
Я чувствую, что это довольно убийственная функция на платформе .Net, потому что единственный другой / предыдущий инструмент, который у вас есть для такого рода инкапсуляции, - это сборки. Если у вас есть небольшой компонент с несколькими связанными типами, которые хотят видеть внутренние детали друг друга, но не хотят, чтобы все эти типы были общедоступными для все, что вы можете сделать? Что ж, вы можете сделать две вещи:
По моему опыту, в крупных программных проектах каждый всегда делает №2, потому что №1 не запускается по разным причинам (люди не хотят 50 маленьких сборок, они хотят 1, 2 или 3 большие сборки, для других возможно- веские причины, не связанные с точкой инкапсуляции, которую я поднимаю (в сторону: все упоминают ILMerge, но никто его не использует)).
Итак, вы выбрали вариант №2. Затем, год спустя, вы, наконец, решаете рефакторинг этого компонента, и вы обнаруживаете, что за последний год 17 других мест теперь вызывают этот `` внутренний '' метод, который на самом деле предназначен только для вызова этого одного другого типа, что делает его действительно трудно исключить этот момент, потому что теперь все зависят от этих деталей реализации. Облом.
Дело в том, что нет хорошего способа создать область / границу инкапсуляции внутри сборки в .Net. Часто «внутреннее» слишком велико, а «личное» слишком мало.
... до F#. С помощью файлов подписи F# вы можете создать область инкапсуляции «этого файла исходного кода», пометив кучу материалов как общедоступные в файле реализации, чтобы весь другой код в файле мог видеть его и участвовать в нем, но затем использовать файл подписи, чтобы скрыть все детали, ожидая узкого общедоступного интерфейса, который компонент предоставляет остальному миру. Это рада. Определите три тесно связанных типа в одном файле, позвольте им видеть детали реализации друг друга, но открывайте для всех только действительно общедоступный материал. Выиграть!
Файлы подписей, возможно, не являются функцией идеальный для границ инкапсуляции внутри сборки, но они представляют собой такую функцию Только, которую я знаю, и поэтому я цепляюсь за них, как спасательный плот в океане.
TL; DR
Сложность - враг. Границы инкапсуляции - оружие против этого врага. «частное» - отличное оружие, но иногда оно слишком мало, чтобы его можно было применить, а «внутреннее» часто бывает слишком слабым, потому что очень много кода (вся сборка и все InternalsVisibleTo) может видеть внутреннее содержимое. F# предлагает более широкую область видимости, чем «частный для типа», но меньшую, чем «вся сборка», и это очень полезно.
Встроенные операторы универсальных типов могут иметь разные общие ограничения:
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)
Чтобы прояснить, что бы произошло, если бы (+) и Exp не были объявлены как встроенные?
@Joh: Операторы больше не будут полиморфными, поэтому, например, вы можете использовать оператор (+) только для одного типа Wrapper в своей программе. Весь код, который я написал выше, по-прежнему будет работать, но с помощью встроенных операторов мы также могли бы добавить два float Wrappers.
Определяемые пользователем числовые литералы могут быть определены путем предоставления модуля, имя которого начинается с 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
Замечательная идея - по умолчанию должно быть включено.
Это очень хороший трюк, но он работает только с G, N, Q, R и Z.
Передача --warnon:1182 компилятору включает предупреждения о неиспользуемых переменных; имена переменных, начинающиеся с подчеркивания, не имеют иммунитета.
Спасибо! Этого не было на странице параметров компилятора! Действительно скрыто.
Интересно, что начиная с F# 2.0 компилятор выдает это предупреждение: FSC: предупреждение FS0075: параметр командной строки --warnon предназначен только для внутреннего использования.
Не совсем скрытый, но как человек, не занимающийся машинным обучением, я довольно долго это ускользало:
Сопоставление с образцом может разложить произвольно глубоко на структуры данных.
Вот пример [невероятно произвольного] вложенного кортежа; это работает со списками или союзами или любыми комбинациями вложенных значений:
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 )
Интересно, что будет, если вы добавите
<appSettings>
<add key = "fsharp-navigationbar-enabled" value = "true" />
</appSettings>
в ваш файл devenv.exe.config? (Используйте на свой риск.)
Есть ли шанс, что вы дадите нам знать, пока мы не попробуем?
Есть ли причина, по которой мне не следует оставлять это включенным? Приятно иметь. Вы знаете, будет ли это в vNext?
Это плохо протестировано, возможно, это может сделать VS более склонным к сбоям. Пока не знаю, будет ли это в vNext ... может быть, есть еще "Навигатор решений", и нужно посмотреть, что мы можем вписать в график ...
Я очень догадываюсь, поэтому каждая функция как-то скрыта;)