Pratique F# extraits
Il y a déjà deux questions F#/fonctionnelle des extraits.
Cependant, ce que je cherche ici sont utile extraits, peu 'helper' fonctions qui sont réutilisables. Ou obscur mais astucieux des modèles que vous ne pouvez jamais me rappeler.
Quelque chose comme:
open System.IO
let rec visitor dir filter=
seq { yield! Directory.GetFiles(dir, filter)
for subdir in Directory.GetDirectories(dir) do
yield! visitor subdir filter}
Je voudrais faire une sorte de pratique de page de référence. En tant que tel il n'y aura pas de bonne réponse, mais j'espère que beaucoup de ceux qui sont bons.
MODIFIER Tomas Petricek a créé un site spécialement pour les F# extraits de http://fssnip.net/.
- S'il vous plaît faire un wiki de la communauté.
- Fait, je croyais que le départ comme une question normale peut fournir la motivation pour certaines réponses initiales.
Vous devez vous connecter pour publier un commentaire.
De style Perl regex correspondant
Il vous permet d'adapter le texte à l'aide de
let test = "monkey" =~ "monk.+"
notation.Opérateur Infixe
Je l'ai obtenu à partir de http://sandersn.com/blog//index.php/2009/10/22/infix-function-trick-for-f aller à cette page pour plus de détails.
Si vous connaissez Haskell, vous pourriez vous retrouver manquant infix de sucre en F#:
Alors que F# ne pas avoir un "vrai" infixe "opérateur, la même chose peut être accompli presque avec autant d'élégance via un pipeline et d'un "backpipeline" (qui savait une chose pareille??)
Multi-Ligne De Chaînes
C'est assez trivial, mais il semble être une caractéristique de F# chaînes qui n'est pas très connu.
Ce produit:
Lorsque le compilateur F# voit un antislash suivi d'un retour chariot à l'intérieur d'une chaîne de caractères littérale, il va supprimer tout le back-slash pour le premier caractère non espace sur la ligne suivante. Cela vous permet d'avoir plusieurs lignes littéraux de chaîne de cette ligne, sans l'aide d'un tas de concaténation de chaîne.
Générique memoization, avec l'aimable autorisation de l'homme lui-même
En utilisant cela, vous pourriez faire un cache de lecteur comme suit:
HashIdentity.Structural
àDictionary
ou elle va utiliser la valeur par défaut .NETTE de référence de l'égalité sur les touches au lieu de F#'s l'égalité structurelle.dict [[|1|], 2; [|1|], 4]
ensuite, vous obtenez un seul de liaison avec la clé[|1|]
qui démontre que c'est en effet à l'aide structurelle de hachage, oui.Simple lecture-écriture pour les fichiers texte
Ces sont triviales, mais de faire de l'accès au fichier de pipeable:
Donc
Et de la combiner avec le visiteur de cité dans la question:
Mise à jour Légère amélioration, si vous voulez être en mesure de lire les fichiers verrouillés (par exemple, fichiers csv qui sont déjà ouverts dans Excel...):
"make file access pipeable:"
Pour la performance intensive des trucs où vous en avez besoin pour vérifier la valeur null
Est d'environ 20x plus vite alors
o = null
nécessite laEquality
contrainte si vous travaillez avec les génériquesisNull
est maintenant un standard inline opérateur et FSharpLint la gentillesse de se plaindre si vous ne l'utilisez pas.Active Modèles, aka "Banana split", sont un outil très pratique qui permettent de construire un match contre plusieurs modèles d'expressions régulières. C'est un peu comme AWK, mais sans la haute performance de DFA's parce que les habitudes sont appariés en séquence jusqu'à ce que l'on y réussit.
Quelques exemples d'utilisation:
Peut-être monade
Voici une brève introduction à la les monades pour les non-initiés.
Option-coalescence des opérateurs
Je voulais une version de la
defaultArg
fonction qui a une syntaxe proche du C# null-coalescence de l'opérateur,??
. Cela me permet d'obtenir la valeur de l'Option, tout en fournissant une valeur par défaut, à l'aide d'un très concis de la syntaxe.Lazy<'a>
pour le deuxième argument, au lieu deunit -> 'a
, puis l'exemple ressembleraitsomeOption |?! lazy(new Default())
'Unitize' une fonction qui ne gère pas les unités
À l'aide de la
FloatWithMeasure
fonction http://msdn.microsoft.com/en-us/library/ee806527(SV.100).aspx.Exemple:
ANCIENNE version:
Bravo à kvb
Échelle/Ratio de la fonction de générateur de
De nouveau, trivial, mais à portée de main.
Exemple:
De transposition d'une liste (vu sur Jomo Fisher blog)
Et ici est une queue-une version récursive qui (à partir de mes croquis de profilage) est légèrement plus lent, mais a l'avantage de ne pas jeter un débordement de la pile lorsque l'intérieur des listes de plus de 10000 éléments (sur ma machine):
Si j'étais intelligent, je vais l'essayer et de paralléliser avec async...
F# Map <-> C# Dictionnaire
(Je sais, je sais, Système.Les Collections.Génériques.Le dictionnaire n'est pas vraiment un "C#" dictionary)
C# F#
(À partir de Brian, ici, avec l'amélioration proposée par Mauricio en commentaire ci-dessous.
(|KeyValue|)
est une configuration active pour la mise en correspondance KeyValuePair - de FSharp.De base équivalent à(fun kvp -> kvp.Key, kvp.Value)
)Alternative intéressante
D'obtenir toutes les lois immuables de la bonté, mais avec le O(1) recherche de la vitesse de Dictionnaire, vous pouvez utiliser le
dict
opérateur, qui retourne un immuable IDictionary (voir cette question).Actuellement, je ne peux pas voir un moyen de convertir directement un Dictionnaire à l'aide de cette méthode, autre que
F# C#
Ce qui est étrange ici, c'est que FSI fera rapport au type (par exemple):
mais si vous nourrissez
dict [("a",1);("b",2)]
retour dans, le FSI rapportsSeq.map
lors de la conversion de KeyValues de tuples. Aussi, vous pouvez utiliser(|KeyValue|)
au lieu defun kvp -> kvp.Key,kvp.Value
(|KeyValue|)
- c'est près de la valeur de son propre extrait de!Arbre-trier /Aplatir un arbre dans une liste
J'ai le texte suivant arbre binaire:
Qui est représenté comme suit:
Une méthode simple pour aplatir l'arbre est:
Ce n'est pas la queue-récursive, et je crois que le
@
opérateur entraîne O(n log n) ou O(n^2) avec déséquilibrée des arbres binaires. Avec un peu de peaufinage, je suis venu avec cette queue-récursive O(n) version:Voici la sortie dans fsi:
flatten
en termes de fois quefold cons [] xs
.(apply append lst1 lst2 lst3)
. Pas récursive si.LINQ-to-XML aides
foo?"href"
?). Et par quelle magie le?<-
"venez à part" dans le milieu? Mon ignorance est mis à nu devant tous?
opérateur dans une méthode de classe statique appeléop_Dynamic
qui prend un paramètre de chaîne. Il se tourne ensuite utilise de la?
opérateur dans les appels à cette méthode, avec la partie après le point d'interrogation comme le paramètre de la chaîne. Donc, à l'exécution, il est tout à typage statique et non dynamique à tous, il fournit simplement quelques belles concis de la syntaxe que vous obtenez pour définir le comportement de. Même principe avec le?<-
de l'opérateur.Somme pondérée des tableaux
Calcul pondéré [n-array] somme de [k-tableau de n-tableaux] de numéros, basé sur un [k-array] de poids
(Copié à partir de cette question, et kvb's réponse)
Compte tenu de ces tableaux
Nous voulons une somme pondérée (par colonne), étant donné que les deux dimensions des tableaux peut être variable.
Première ligne: application Partielle de la première pile.map2 fonction de poids produit une nouvelle fonction (Tableau).carte ((*) le poids) qui est appliqué (pour chaque poids) de chaque tableau en arr.
Deuxième ligne: Tableau.réduire, c'est comme pli, sauf qu'il commence à la deuxième valeur, et utilise la première initiale de l'état. Dans ce cas, chaque valeur est une "ligne" de notre tableau de tableaux. Ainsi, à l'application d'un Tableau.map2 (+) sur les deux premières lignes signifie que nous somme les deux premiers tableaux, qui nous laisse avec un nouveau tableau, que nous avons ensuite (Tableau.réduire) la somme de nouveau sur la prochaine (dans ce dernier cas) tableau.
Résultat:
Tests de Performance
(Trouvé ici et mis à jour pour la dernière version de F#)
stopwatch.Elapsed.TotalSeconds
est plus précis.OK, cela n'a rien à voir avec les extraits de code, mais j'oublie ceci:
Si vous êtes dans la fenêtre interactive, vous frappez F7 pour revenir à la fenêtre de code (sans désélectionner le code qui vous a juste couru...)
Allant de la fenêtre de code F# fenêtre (et aussi pour ouvrir le F# fenêtre) Ctrl Alt F
(sauf CodeRush a volé vos fixations...)
DataSetExtensions F# DataReaders
System.Data.DataSetExtensions.dll ajoute la capacité de traiter un
DataTable
comme unIEnumerable<DataRow>
ainsi que unboxing les valeurs des cellules individuelles d'une manière qui s'poignéesDBNull
par Système de soutien.Nullable. Par exemple, en C#, nous pouvons obtenir la valeur d'un entier de la colonne qui contient les valeurs null, et de préciser queDBNull
devrait être par défaut à zéro avec un très concis syntaxe:Il y a deux domaines où DataSetExtensions manquent cependant. Tout d'abord, il ne prend pas en charge
IDataReader
et, deuxièmement, elle ne prend pas en charge le F#option
type. Le code suivant fait à la fois - il permet à unIDataReader
d'être traité comme unseq<IDataRecord>
, et il peut unbox valeurs à partir d'un lecteur ou d'un ensemble de données, avec le soutien de F# options ou d'un Système.Nullable. Combinée avec l'option-coalescence de l'opérateur dans une autre réponse, ce qui permet le code comme suit lorsque l'on travaille avec un DataReader:Peut-être plus idiomatiques F# façon d'ignorer la base de données les valeurs null serait...
En outre, l'extension des méthodes définies ci-dessous sont utilisables à partir de deux F# et en C#/VB.
La manipulation des arguments dans une application en ligne de commande:
(J'avais un vague souvenir de cette technique, inspirée par Robert Pickering, mais ne peut pas trouver une référence maintenant)
Pratique du fonctionnement de la mémoire cache qui garde jusqu'à
max
(key,reader(key))
dans un dictionnaire et d'utiliser unSortedList
pour suivre le MRU clésLa Création De XElements
Rien d'étonnant, mais je continue de se faire prendre par la conversion implicite de XNames:
Par paires et des paires de
J'ai toujours s'attendre à Seq.paires de me donner [(1,2);(3;4)] et pas [(1,2);(2,3);(3,4)]. Étant donné que ni existe pas dans la Liste, et que je devais à la fois, voici le code de référence pour l'avenir. Je pense elles sont la queue récursive.
Naïf CSV reader (c'est à dire, de ne pas gérer quoi que ce soit de méchant)
(À l'aide de filereadlines et de la Liste.la transposition d'autres réponses ici)
Exemple
Plage de dates
simple mais utile liste de dates entre
fromDate
ettoDate
activer /désactiver le code sql
Plus trivial que la plupart sur cette liste, mais pratique néanmoins:
Je suis toujours en prenant sql dans et hors de code pour le déplacer vers un sql environnement au cours du développement. Exemple:
doit être "dépouillé" pour:
en gardant la mise en forme. C'est une douleur à dépouiller le symbole de code de l'éditeur sql, puis les mettre à nouveau la main quand j'en ai le sql travaillé. Ces deux fonctions basculer le sql en arrière à partir de code dépouillé:
puis lorsque vous êtes prêt à mettre dans votre code source du fichier:
J'avais amour pour se débarrasser du fichier d'entrée, mais ne peut même pas commencer à analyser la façon de faire que cela se produise. quelqu'un?
edit:
J'ai compris comment faire pour supprimer l'exigence d'un fichier de ces fonctions par l'ajout d'un windows forms boîte de dialogue d'entrée/sortie. Trop de code à montrer, mais pour ceux qui voudraient faire une telle chose, c'est comment je l'ai résolu.
let replace f r (s:string) = s.Replace(f,r)
etlet regreplace p r s = Regex.Replace(s, p, r)
(non testé)Le Triangle de Pascal (hey, quelqu'un pourrait trouver utile)
Si nous voulons créer quelque chose comme ceci:
Assez facile:
La
next
fonction renvoie une nouvelle liste dans laquelle chaque élément[i] = item[i] + élément[i + 1].Voici la sortie dans fsi:
Pour les plus aventureux, voici une queue-une version récursive:
Aplatir une Liste
si vous avez quelque chose comme ceci:
et veulent "aplatir" il vers le bas pour un seul de la liste de sorte que le résultat ressemble à ceci:
il peut être fait ainsi:
List.concat
. (Ce qui m'arrive tout le temps de codage d'une fonction découvrant alors qu'il est déjà là!). Il serait intéressant de voir si il y a une fonction qui fait ce "de manière récursive' (c'est à dire pour[[[1;2;3;];[4;5;6]];[[1;2;3;];[4;5;6]]]
)List.concat
est certainement le chemin à faire, avant je l'ai trouvé j'ai été en utilisantList.collect id
Interprétations de la liste pour float
Ce
[23.0 .. 1.0 .. 40.0]
a été marquée comme obsolète quelques versions soutenu.Mais apparemment, cela fonctionne:
(BTW, il y a une virgule flottante gotcha là. Découvert à fssnip - l'autre endroit pour F# extraits)
Parallèle de la carte
Array.Parallel.map
maintenant.Établissant un record à null
let f : Foo = Unchecked.defaultof<_>