2008-10-08 2 views
23

Это беспрепятственная попытка аналогичного вопроса C#.Скрытые особенности F #

Итак, каковы ваши любимые функции F # (или нет)?

Большинство функций, которые я использовал до сих пор, не совсем скрыты, но были довольно освежающими. Подобно тому, насколько тривиальным является перегрузка операторов по сравнению с C# или VB.NET.

И Async<T> помог мне сбрить какой-то настоящий уродливый код.

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

ответ

1

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

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

+2

Я очень думаю, поэтому каждая функция как-то скрыта;) – wishi 2009-11-03 09:29:48

6

Да, F # не имеет «скрытые» функции, но он уверен, действительно есть много энергии, упакованной в простом языке. Менее известная особенность языка - это то, где вы можете в принципе enable duck typing, несмотря на то, что F # статично типизирован.

7

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

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

для примера.

3

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

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

+0

Мне нравится использовать FSI для небольших скриптов, и я фактически использовал некоторые файлы .fsx для вещей. Однако, по крайней мере, по моему опыту, время запуска, необходимое для файлов .fsx, слишком велико для сценариев общего назначения. Я по-прежнему предпочитаю командные файлы и скрипты Perl для сценариев. – Juliet 2009-12-07 05:39:18

+0

Попробуйте PowerShell, и вы не пожалеете :) – stej 2011-11-05 23:49:35

6

Смотрите этот вопрос

F# operator "?"

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

10

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

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

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

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

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

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

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

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

TL;

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

2

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

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) 
+0

Просто, чтобы уточнить, что произойдет, если (+) и Exp не были объявлены как inline? – Joh 2009-12-05 15:41:54

+0

@Joh: Операторы больше не будут полиморфными, поэтому, например, вы можете использовать оператор (+) только для одного типа Wrapper в вашей программе. Весь код, который я написал выше, по-прежнему будет работать, но с встроенными операторами мы также можем добавить два `float Wrappers`. – kvb 2009-12-05 21:34:18

29

Пользовательские числовые литералы могут быть определены путем предоставления модуля, название которого начинается с 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 
+2

Удивительная идея - должна быть включена по умолчанию. – forki23 2010-07-01 11:57:17

8

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

5

Не совсем скрытый, но как не МЛ человек это вырвалось у меня довольно долгое время:

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

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

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) 
9

Интересно, что произойдет, если добавить

<appSettings> 
    <add key="fsharp-navigationbar-enabled" value="true" /> 
</appSettings> 

в файл devenv.exe.config? (Используйте на свой страх и риск.)

Смежные вопросы