2010-05-08 4 views
6

Ce n'est pas un problème important en pratique, mais j'aimerais voir un exemple de tacit programming en F # où mes fonctions sans point peuvent avoir plusieurs arguments (pas sous la forme d'une liste ou d'un tuple) .Tacit style de programmation utilisant F #

Et d'autre part, comment ces fonctions peuvent manipuler une structure de données complexe . J'essaie dans F # Interactive, mais je n'ai pas encore de succès.

J'ai essayé, par exemple:

> (fun _ -> (fun _ -> (+))) 333 222 111 555 

Est-ce la bonne façon?

Et:

> (fun _ -> (fun _ -> (+))) "a" "b" "c" "d";; 

val it : string = "cd" 
+3

Vous devriez utiliser "sans point" plutôt que "inutile". C'est le terme standard. :) –

Répondre

4

F # ne contient pas certaines des fonctions de base qui sont disponibles dans Haskell (principalement parce que F # programmeurs préfèrent généralement le style explicite de la programmation et utiliser le style de Pointfree que dans les cas les plus évidents , où cela ne nuit pas à la lisibilité).

Cependant, vous pouvez définir quelques combinateurs de base comme celui-ci:

// turns curried function into non-curried function and back 
let curry f (a, b) = f a b 
let uncurry f a b = f (a, b) 

// applies the function to the first/second element of a tuple 
let first f (a, b) = (f a, b) 
let second f (a, b) = (a, f b) 

Maintenant, vous pouvez mettre en œuvre la fonction d'ajouter des longueurs de deux chaînes en utilisant combinators comme suit:

let addLengths = 
    uncurry (((first String.length) >> (second String.length)) >> (curry (+))) 

Ce construit deux fonctions qui appliquent String.length au premier/deuxième élément d'un tuple, puis les compose et ajoute ensuite les éléments du tuple en utilisant +. Le tout est enveloppé dans uncurry, de sorte que vous obtenez une fonction de type string -> string -> int.

+0

J'ai vérifié cela dans FSI et ça marche! Merci beaucoup; btw, pourriez-vous expliquer comment êtes-vous arrivé à cette syntaxe de composition tuple-fonction? Je veux dire '(premier String.length) >> (second String.length)' Cela me semble quelque peu inhabituel;) – Bubba88

+0

Cela est réalisé en utilisant la fonction composition '>>'. Par exemple 'f >> g' signifie que pour un argument' x', il appellera 'g (f (x))'. Dans le cas ci-dessus, la première fonction ('first String.length') transforme un tuple' string * string' en un tuple 'int * string' et la deuxième fonction (' second String.length') le transforme en 'int * int' contenant les longueurs. –

+0

Vous appliquez pratiquement les flèches pour F #;) Ok, pourquoi pas - Les flèches ont été inventées comme une combinaison de monades et de programmation tacite. – Dario

2

En F #, l'arité des fonctions est fixé, de sorte que vous n'allez pouvoir écrire à la fois

(op) 1 2 

et

(op) 1 2 3 4 

pour tout opérateur donné op. Vous devrez utiliser une liste ou une autre structure de données si c'est ce que vous voulez. Si vous essayez simplement d'éviter les variables nommées, vous pouvez toujours faire "1 + 2 + 3 + 4". La façon la plus idiomatique d'ajouter une liste de nombres en F # est List.sum [1;2;3;4], ce qui évite également les variables.