Lorsque vous travaillez avec des fonctions d'ordre supérieur (c.-à-fonctions qui renvoient d'autres fonctions et/ou prendre d'autres fonctions en tant que paramètres), vous devez toujours fournir quelque chose comme paramètre, mais il n'y a pas toujours une réelle la transformation des données que vous souhaitez appliquer.
Par exemple, la fonction Seq.collect
aplatit une séquence de séquences et prend une fonction qui renvoie la séquence "imbriquée" pour chaque élément de la séquence "externe". Par exemple, voici comment vous pouvez obtenir la liste de tous les petits-enfants d'un contrôle de l'interface utilisateur d'une sorte:
let control = ...
let allGrandChildren = control.Children |> Seq.collect (fun c -> c.Children)
Mais beaucoup de fois, chaque élément de la séquence sera déjà une séquence par lui-même - par exemple , vous pouvez avoir une liste de listes:
let l = [ [1;2]; [3;4]; [5;6] ]
Dans ce cas, la fonction des paramètres que vous passez à Seq.collect
a besoin de retourner simplement l'argument:
let flattened = [ [1;2]; [3;4]; [5;6] ] |> Seq.collect (fun x -> x)
cette expres sion fun x -> x
est une fonction qui retourne juste son argument, également connu sous le nom "fonction d'identité".
let flattened = [ [1;2]; [3;4]; [5;6] ] |> Seq.collect id
Ses cultures d'utilisation si souvent lorsque vous travaillez avec des fonctions d'ordre supérieur (comme ci-dessus) Seq.collect
qu'il mérite une place dans la bibliothèque standard.
Un autre exemple convaincant est Seq.choose
- une fonction qui filtre une séquence de valeurs Option
et les déballe en même temps. Par exemple, voici comment vous pouvez analyser toutes les chaînes sous forme de nombres et jeter ceux qui ne peuvent pas être analysées:
let tryParse s = match System.Int32.TryParse s with | true, x -> Some x | _ -> None
let strings = [ "1"; "2"; "foo"; "42" ]
let numbers = strings |> Seq.choose tryParse // numbers = [1;2;42]
Mais si vous êtes déjà donné une liste de valeurs Option
pour commencer? La fonction d'identité à la rescousse!
let toNumbers optionNumbers =
optionNumbers |> Seq.choose id
Intéressant de noter le fond mathématique aussi bien. Avoir un objet «ne rien faire» donne une structure importante.Comme zéro est une identité pour les nombres sous addition, et l'un est une identité pour les nombres sous multiplication, donc 'id' est une identité pour l'ensemble des fonctions sous la composition. Et dans les langages fonctionnels, vous voudrez souvent manipuler des fonctions en tant qu'objets, effectuer des opérations sur eux, etc. –
@matt_t_gregg Si vous postez cela en guise de réponse, je suis sûr que vous obtiendrez quelques upvotes. –
@FyodorSoikin J'étais assez contente que votre réponse couvre les aspects pratiques de la nécessité et de l'utilisation - la chose mathématique que je pensais être plus intéressante. –