Domanda

Sto provando a entrare e uscire da F # da un po ', ma continuo a rimandare. Perché?

Perché non importa quale risorsa di "principianti" cerco di vedere, vedo esempi molto semplici che iniziano a usare l'operatore - > .

Tuttavia, finora non ho trovato nulla che fornisca una chiara e semplice spiegazione del significato di questo operatore. È come se fosse così ovvio che non ha bisogno di spiegazioni nemmeno per completare i neofiti.

Devo quindi essere davvero denso o forse sono quasi 3 decenni di esperienza precedente a trattenermi.

Qualcuno può per favore, spiegarlo o indicare una risorsa veramente accessibile che lo spiega?

È stato utile?

Soluzione

'- >' non è un operatore. Appare nella sintassi F # in diversi punti e il suo significato dipende da come viene usato come parte di un costrutto più grande.

All'interno di un tipo, '- >' descrive i tipi di funzione come le persone hanno descritto sopra. Ad esempio

let f : int -> int = ...

dice che 'f' è una funzione che accetta un int e restituisce un int.

All'interno di una lambda (" cosa che inizia con una parola chiave "divertente" "), "- >" è la sintassi che separa gli argomenti dal corpo. Ad esempio

fun x y -> x + y + 1

è un'espressione che definisce una funzione a due argomenti con l'implementazione data.

All'interno di " match " costruire, "- >" è una sintassi che separa i pattern dal codice che dovrebbe essere eseguito se il pattern è abbinato. Ad esempio, in

match someList with
| [] -> 0
| h::t -> 1

le cose a sinistra di ogni '- >' sono schemi e la roba a destra è ciò che accade se lo schema a sinistra è stato abbinato.

La difficoltà di comprensione può essere radicata nel presupposto errato che "- >" è "operatore" con un unico significato. Un'analogia potrebbe essere ". & Quot; in C #, se non hai mai visto alcun codice prima e prova ad analizzare ". " operatore basato sulla ricerca di " obj.Method " e "3,14" e "System.Collections", potresti essere molto confuso, perché il simbolo ha significati diversi in contesti diversi. Una volta che conosci abbastanza la lingua per riconoscere questi contesti, tuttavia, le cose diventano chiare.

Altri suggerimenti

Significa sostanzialmente "quotare a". Leggi in quel modo o come "si trasforma in" o qualcosa del genere.

Quindi, dal F # in 20 minuti tutorial,

> List.map (fun x -> x % 2 = 0) [1 .. 10];;
val it : bool list
= [false; true; false; true; false; true; false; true; false; true]
  

Il codice (fun i - > i% 2 = 0) definisce   una funzione anonima, chiamata lambda   espressione, che ha un parametro x e   la funzione restituisce il risultato di " x   % 2 = 0 " ;, ovvero se x è   anche.

Prima domanda: hai familiarità con le espressioni lambda in C #? In tal caso il - > in F # è uguale a = > in C # (penso che tu abbia letto "va a").

Il - > operatore può essere trovato anche nel contesto della corrispondenza dei modelli

match x with
| 1 -> dosomething
| _ -> dosomethingelse

Non sono sicuro che questa sia anche un'espressione lambda o qualcos'altro, ma immagino che il 'andare a' valga ancora.

Forse a cui ti riferisci davvero sono le risposte "criptiche" del parser F #:

> let add a b = a + b
val add: int -> int -> int

Questo significa (come spiega la maggior parte degli esempi) che add è un 'val' che accetta due ints e restituisce un int. Per me questo era totalmente opaco per cominciare. Voglio dire, come faccio a sapere che add non è un valore che accetta un int e restituisce due ints?

Beh, il fatto è che, in un certo senso, lo fa. Se do solo aggiungere un int, torno indietro a (int - > int):

> let inc = add 1
val inc: int -> int

Questo (curry) è una delle cose che rende F # così sexy, per me.

Per informazioni utili su F #, ho scoperto che i blog sono MOLTO più utili di qualsiasi "documentazione" ufficiale: ecco alcuni nomi da controllare

(a - > b) significa "funzione da a a b". Nell'annotazione del tipo, indica un tipo di funzione. Ad esempio, f: (int - > String) significa che f si riferisce a una funzione che accetta un numero intero e restituisce una stringa. È anche usato come un costruttore di tali valori, come in

val f : (int -> int) = fun n -> n * 2

che crea un valore che è una funzione da un certo numero n allo stesso numero moltiplicato per due.

Ci sono già molte ottime risposte qui, voglio solo aggiungere alla conversazione un altro modo di pensarci.

'- > 'significa funzione.

'a - > 'b è una funzione che accetta una' a e restituisce una 'b

('a *' b) - > ('c *' d) è una funzione che accetta una tupla di tipo ('a,' b) e restituisce una tupla di ('c,' d). Come int / string restituisce float / char.

Dove diventa interessante è il caso in cascata di 'a - > 'b - > 'C. Questa è una funzione che accetta una 'a e restituisce una funzione (' b - > 'c), o una funzione che accetta una' b - > 'C.

Quindi se scrivi:  let f x y z = ()

Il tipo sarà f: 'a - > 'b - > 'c - > unità, quindi se si applica solo il primo parametro, il risultato sarebbe una funzione curry 'b - > 'c - > 'unità.

Da Microsoft :

  

I tipi di funzione sono i tipi dati a   valori di funzione di prima classe e sono   scritto int - > Int. Sono simili   ai tipi di delegati .NET, tranne loro   non vengono dati nomi. Tutta la funzione F #   gli identificatori possono essere usati come di prima classe   valori di funzione e anonimo   i valori delle funzioni possono essere creati usando   la forma di espressione (divertente ... - > ...).

Molte grandi risposte a queste domande, grazie persone. Vorrei mettere qui una risposta modificabile che riunisce le cose.

Per chi ha familiarità con la comprensione di C # - > essendo uguale a = > L'espressione lamba è un buon primo passo. Questo utilizzo è: -

fun x y -> x + y + 1

Può essere inteso come equivalente a: -

(x, y) => x + y + 1;

Comunque è chiaro che - > ha un significato più fondamentale che deriva dal concetto che una funzione che accetta due parametri come quello sopra può essere ridotta (è il termine corretto?) a una serie di funzioni che accettano solo un parametro.

Quindi quando quanto sopra è descritto in questo modo: -

Int -> Int -> Int

Mi ha davvero aiutato a sapere che - > è giusto associativo quindi si può considerare quanto sopra: -

Int -> (Int -> Int)

Aha! Abbiamo una funzione che accetta Int e restituisce (Int - > Int) (una funzione al curry?).

La spiegazione che - > può anche apparire come parte del tipo definiton anche aiutato. (Int - > Int) è il tipo di qualsiasi funzione che accetta un Int e restituisce un Int.

Anche utile è - > appare in un'altra sintassi come la corrispondenza ma lì non ha lo stesso significato? È corretto? Non sono sicuro che lo sia. Sospetto che abbia lo stesso significato, ma non ho ancora il vocabolario per esprimerlo.

Nota che lo scopo di questa risposta non è quello di generare ulteriori risposte ma di essere modificato in modo collaborativo da parte tua gente per creare una risposta più definitiva. Inutilmente sarebbe bene che tutte le incertezze e il fluf (come questo paragrafo) fossero rimossi e che fossero aggiunti esempi migliori. Proviamo a mantenere questa risposta il più accessibile possibile ai non iniziati.

Nel contesto della definizione di una funzione, è simile a = > dall'espressione lambda in C # 3.0.

F#: let f = fun x -> x*x
C#: Func<int, int> f = x => x * x;

Il - > in F # viene anche usato nella corrispondenza dei pattern, dove significa: se l'espressione corrisponde alla parte tra | e - > , quindi ciò che viene dopo - > dovrebbe essere restituito come risultato:

let isOne x = match x with
 | 1 -> true
 | _ -> false

La cosa bella di linguaggi come Haskell (è molto simile in F #, ma non conosco la sintassi esatta - questo dovrebbe aiutarti a capire - > ;, però) è che puoi applicare solo parti dell'argomento , per creare le funzioni al curry :

adder n x y = n + x + y

In altre parole: " dammi tre cose e le aggiungerò " ;. Quando ci lanci dei numeri, il compilatore inferirà i tipi di n x e y. Di 'che scrivi

adder 1 2 3

Il tipo di 1, 2 e 3 è Int. Pertanto:

adder :: Int -> Int -> Int -> Int

Cioè, dammi tre numeri interi, e alla fine diventerò un numero intero, o la stessa cosa che dire:

five :: Int
five = 5

Ma ecco la bella parte! Prova questo:

add5 = adder 5

Come ricordi, l'adder prende un int, un int, un int e ti restituisce un int. Tuttavia, questa non è tutta la verità, come vedrai a breve. In effetti, add5 avrà questo tipo:

add5 :: Int -> Int -> Int

Sarà come se tu avessi "rimosso" " degli interi (il più a sinistra) e incollato direttamente alla funzione. Guardando più da vicino la firma della funzione, notiamo che - > sono associativi, vale a dire:

addder :: Int -> (Int -> (Int -> Int))

Questo dovrebbe chiarire: quando dai ad adder il primo numero intero, valuterà ciò che è alla destra della prima freccia, oppure:

add5andtwomore :: Int -> (Int -> Int)
add5andtwomore = adder 5

Ora puoi usare add5andtwomore invece di " adder 5 " ;. In questo modo, puoi applicare un altro numero intero per ottenere (diciamo) " add5and7andonemore " ;:

add5and7andonemore :: Int -> Int
add5and7andonemore = adder 5 7

Come vedi, add5and7andonemore vuole esattamente un altro argomento, e quando lo dai, diventerà improvvisamente un numero intero!

  > add5and7andonemore 9
 => ((add5andtwomore) 7) 9
 => ((adder 5) 7) 9)
<=> adder 5 7 9

Sostituendo i parametri in adder (n x y) per (5 7 9), otteniamo:

  > adder 5 7 9 = 5 + 7 + 9
 => 5 + 7 + 9
 => 21

In effetti , plus è anche solo una funzione che accetta un int e ti restituisce un altro int, quindi quanto sopra è davvero più simile a:

  > 5 + 7 + 9
 => (+ 5 (+ 7 9))
 => (+ 5 16)
 => 21

Ecco qua!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top