2010-09-29 9 views
5

Credo che questo sia in qualche modo collegato a this question, ma non essendo sicuro e dato che non c'è una risposta vera e propria c'è, qui vado:
a Scala c'è è possibile scrivere codice come ad esempio:F # stenografia di chiamare il metodo in oggetto in lambda

aStringArray.map(_.toUpperCase())

che è una scorciatoia per:

aStringArray.map(s => s.toUpperCase())

c'è qualcosa di simile in F # o un modo di attuarla (senza che l'operatore o l'uso pesante di riflessione?)? Se ciò non è possibile, è considerato come una funzionalità linguistica per una versione futura? (Ho davvero la verbosità delle funzioni solo per chiamare un metodo su un oggetto in una chiusura!).

risposta

6

Come Dario sottolinea che una funzione come la sintassi _.Foo() in Scala non è attualmente disponibile in F #, quindi dovrai scrivere esplicitamente una funzione lambda usando fun a -> a.Foo().

Per quanto ne so, una domanda come questa appare di tanto in tanto nelle discussioni di F #, quindi è stata sicuramente considerata dal team di F #. È un po 'complicato (es. Vuoi consentire solo usi membri o altri usi, ad esempio _ + 10, e quale sarebbe lo scopo dell'espressione lambda?) Inoltre, il valore della funzione è relativamente basso rispetto ad altre cose che potrebbero essere fatto ... Comunque, sarebbe bello averlo!

Questo potrebbe essere anche un motivo per cui molti tipi di F # espongono le operazioni come entrambi i membri (utilizzabili nello stile OO) e funzionano in un modulo (per lo stile funzionale). Penso che potresti considerarlo una buona pratica di F # (ma dipende dalle tue preferenze di progettazione). Es .:

type Foo(a:int) = 
    member x.Add(b:int) = a + b 

// Attribute allows you to define module with the same name 
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>] 
module Foo = 
    let add b (v:Foo) = v.Add(b) 

quindi è possibile utilizzare sia fun v -> v.Add(10) e Foo.add 10 per creare un valore della funzione. Sfortunatamente, il tipo String non ha il modulo corrispondente con tutte le funzioni nelle librerie principali F #, quindi dovresti scriverlo da solo.

-1

Questa non è proprio la risposta che volevi, ma al momento lavoro su questo creando funzioni statiche fittizie (se avrò bisogno della stessa cosa più volte), poiché è più carina della sintassi lambda:

let toupper (s:string) = s.ToUpper() 
aStringArray.map toupper 
+0

'(fun s -> s.toupper())' – Brian

+0

... o 'let toUpper (s: string) = s.ToUpper()' se si desidera definire una funzione con nome. –

+0

@Tomas, sì, questo è quello che stavo puntando, ho dimenticato la definizione del tipo. – Benjol

5

Utilizzare semplicemente fun s -> s.ToUpper() come parametro, che crea lo stesso tipo di funzione anonima eseguita da Scala.

Si noti che questo nifty _ trucco da Scala non (attualmente) esiste in F #, ma se non si stava chiamando un metodo dell'oggetto, si potrebbe utilizzare la valutazione parziale come in

filter ((=) 42) list 
1

Vedi questo thread del forum:

http://cs.hubfs.net/forums/permalink/13313/13319/ShowThread.aspx#13319

La # team di F è stato più di questo territorio un certo numero di volte, ma nulla praticabile è mai venuto fuori. A questo punto penso sia dubbio che introdurremo un nuovo modulo sintattico che consente di risparmiare meno di 10 caratteri.

+1

È un piccolo numero di personaggi ma lo rende concettualmente molto più semplice, almeno per me. Ovviamente sarebbe più semplice se si pensasse che 'a.b' applichi un operatore punto. Quindi '.b' sarebbe una sintassi naturale. –

+0

Oltre al salvataggio in termini di caratteri, che data la frequenza con cui questo codice appare quando si usano le librerie Oo classiche sarebbe comunque enorme, c'è anche un altro enorme vantaggio: si legge molto meglio. – em70

Problemi correlati