2013-05-14 23 views

risposta

23

La risposta breve è no. In genere utilizzi una funzione di ordine superiore per esprimere la stessa funzionalità. Esiste un certo numero di funzioni che ti permettono di farlo, corrispondenti a modelli diversi (quindi se descrivi di cosa hai bisogno, qualcuno potrebbe darti una risposta migliore).

Per esempio, tryFind funzione restituisce il primo valore da una sequenza per la quale un dato predicato ritorna true, che permette di scrivere qualcosa di simile:

seq { 0 .. 100 } |> Seq.tryFind (fun i -> 
    printfn "%d" i 
    i=66) 

In pratica, questo è il modo migliore per andare se stai esprimendo una logica di alto livello e c'è una funzione corrispondente. Se si ha realmente bisogno di esprimere qualcosa di simile break, è possibile utilizzare una funzione ricorsiva:

let rec loop n = 
    if n < 66 then 
    printfn "%d" n 
    loop (n + 1) 

loop 0  

Un'opzione più esotici (che non è così efficiente, ma può essere piacevole per DSL) è che si può definire un'espressione di calcolo che ti consente di scrivere break e continue. Here is an example, ma come ho detto, non è così efficiente.

4

È necessario modificarlo in un ciclo while.

let (i, ans) = (ref 0, ref -1) 
while(!i < 100 and !ans < 0) do 
if !i = 66 then 
    ans := !i 
ans 

(Questo rompe quando mi arriva a 66 - ma sì la sintassi è molto diverso, viene introdotta un'altra variabile, ecc)

+1

E poiché non incrementa 'i', ci vuole molto tempo. :-) –

2

Questo è veramente brutto, ma nel mio caso ha funzionato.

let mutable Break = false 
while not Break do 
    //doStuff 

    if breakCondition then 
     Break <- true 
done 

Questo è utile per cicli do-while, poiché garantisce che il ciclo venga eseguito almeno una volta.

Spero ci sia una soluzione più elegante. Non mi piace il ricorsivo, perché ho paura degli stack overflow. :-(

0
seq { 
    for i = 0 to 99 do 
     if i = 66 then yield() 
} 
|> Seq.tryItem 0 
|> ignore 
0

Per questo tipo di problemi è possibile utilizzare una funzione ricorsiva

let rec IfEqualsNumber start finish num = 
    if start = finish then false 
    elif 
     start = num then true 
    else 
     let start2 = start + 1 
     IfEqualsNumber start2 finish num 
0

Prova questo:.

exception BreakException 

try 
    for i = 0 to 99 do 
     if i = 66 then 
     raise BreakException 
with BreakException ->() 

So che alcune persone non piace usare eccezioni, ma ha dei pregi:

  • Tu non pensare alla complicata funzione ricorsiva. Di perché è possibile farlo, ma a volte è inutilmente fastidioso e l'utilizzo dell'eccezione è più semplice.

  • Questo metodo consente di interrompere a metà del corpo del circuito. (Break "flag" metodo è anche semplice ma consente solo di rompere alla fine del corpo del loop.)

  • Si può facilmente uscire dal ciclo annidato.