Pratiche pratiche di programmazione funzionale

7

Non ho un particolare problema di codifica a portata di mano questo è solo un esercizio per migliorare il mio processo di pensiero.

Pochi mesi fa ho iniziato a conoscere la programmazione funzionale (principalmente in R) e me ne sono innamorato. Ogni tanto cerco di pensare a problemi che potrebbero essere (correzione: che potrei trovare) difficili da risolvere in FP. Recentemente ho pensato a una situazione in cui potrei essere più interessato a programmare utilizzando la programmazione imperativa.

Mi sembra che tutte le funzioni di ordine superiore come map o reduce possano scorrere l'intera lista fornita a loro che ha senso. Come eviterai di ripetere l'intera lista nella programmazione funzionale per qualsiasi motivo - es. la lista è troppo lunga, la lista è in realtà una serie infinita, valutare ogni articolo è molto costoso ecc.

Quindi per rendere questo problema più specifico diciamo che ho un array e voglio restituire ogni membro dal membro zeroth al primo elemento il cui valore è maggiore di 10, ma voglio smettere di cercare nell'elenco una volta che trovo quell'elemento maggiore di 10.

Come risolveresti questo?

Array di esempio: 1 2 3 1 2 3 11 1 2 3 1 2 3

Non sto cercando una risposta specifica in R Ho visto abbastanza Haskell & Scala di solito ha senso del codice.

EDIT:

Ho dimenticato di menzionare il motivo per cui preferirei usare la programmazione imperativa qui. Trovo che sia più facile interrompere l'iterazione attraverso l'array sopra con while / until loops perché una volta raggiunto l'interprete di condizione di terminazione si chiude il ciclo, ma la mappa non conserva informazioni sugli elementi precedenti e riduce i risolti che però continuo per scorrere fino alla fine della mia lista.

    
posta sgp667 20.02.2018 - 20:48
fonte

2 risposte

13

Quello di cui vuoi leggere di più è valutazione pigra Questo significa in sostanza aspettare fino all'ultimo minuto possibile per fare un po 'di lavoro. Quindi se hai il seguente codice Haskell:

takeWhile (<= 10) $ map (+1) [1..]

[1..] è un elenco infinito, che aggiungi 1 a ogni elemento, quindi prendi tutti gli elementi nell'elenco che sono <= 10. Tuttavia, l'aggiunta di uno viene eseguita su richiesta, quindi non per ottenere il risultato, devi avere map dell'intero elenco infinito.

Haskell è pigro per impostazione predefinita. Nella maggior parte delle altre lingue, devi esplicitamente chiedere pigrizia. In Scala, ciò avviene utilizzando una raccolta lenta come una vista, un flusso o un iteratore. Non conosco R.

    
risposta data 20.02.2018 - 21:06
fonte
1

Modifica: questa non è una buona pratica scusa! Qui solo un esempio di come farlo manualmente in un approccio funzionale. La migliore pratica è ovviamente quella di utilizzare la funzione di ordine superiore disponibile pronta per farlo.

Un esempio in ocaml che implementa a mano il ciclo per un elenco:

    let takewhile l f =
      let rec loop a l =
        match l with
        | [] -> a
        | hd :: tl ->
          if (f hd)
            then hd :: a else
            loop (hd :: a) tl in
      loop [] l 
      |> List.rev
    
risposta data 14.03.2018 - 09:04
fonte

Leggi altre domande sui tag