Questo modello Haskell ha un nome?

3

Recentemente ho trovato uso per le seguenti funzioni di Haskell:

feed :: (a -> (a, b)) -> a -> Int -> (a, [b])
feed f input 0 = (input, [])
feed f input n
  | n < 0 = error "feed f input n: n < 0"
  | otherwise = (final, out:prev)
    where (next, out) = f input
      (final, prev) = feed f next $ pred n

nest :: (a -> a) -> a -> Int -> a
nest f x 0 = x
nest f x n
  | n < 0 = error "nest f x n: n < 0"
  | otherwise = f $ nest f x $ pred n

feed calcola una funzione attraverso qualche input a , con la funzione che restituisce un nuovo input per la chiamata successiva, oltre a "emettere" un output, che viene raccolto. nest funziona allo stesso modo, ma non lascia funzioni emit .

Questo mi sembra "Monadico" terribilmente, e mi sembra che qualcosa di Control.Monad dovrebbe già fare questo (mi sono sorpreso a provare a reimplementare cose come sequence , mapM , ecc. ., per necessità prima, dato che sono un principiante con Haskell e non so bene cosa c'è nella libreria e cosa non lo è.

Esiste già qualcosa come la precedente (forse in un contesto più generale?)? Ho esaminato i documenti (almeno quelli con cui ho familiarità) e non riesco a trovare nulla, anche se questo sembra un modello comune. Esempio di utilizzo:

let pick10 rng = feed (swap . randomR (1, 10)) rng 10
    
posta VF1 12.01.2015 - 05:39
fonte

2 risposte

7

Nota: questa risposta potrebbe essere un po 'più di base di quella che stai cercando. Forse qualcuno lo troverà utile.

feed è un po 'come Data.List. unfoldr. Non è vincolato a Int s. Potresti generalizzare il tuo oltre Enum s se lo desideri. iterate è simile, ma produce un elenco infinito.

Main Data.List> unfoldr (\x -> if x > 9 then Nothing else Just (x, x + 1)) 0
[0,1,2,3,4,5,6,7,8,9] 
Main Data.List> feed (\x -> (x + 1, x)) 0 10
(10,[0,1,2,3,4,5,6,7,8,9])

nest è un po 'come iterate a causa di liste infinite. Di nuovo, non vincolato dal tipo Int .

*Main Data.List> iterate (+ 1.5) 2.7 !! 10
17.7
*Main Data.List> nest (+ 1.5) 2.7 10
17.7

Per quanto riguarda Monadic, non ne sono sicuro. [a] è una Monade incorporata, e ovviamente unfoldr f per qualunque cosa f è una bella a -> [a] . Penso che potresti definire un'istanza Monad per il tuo tipo (a, [b]) che ha lasciato una traccia e ha continuato con il "nuovo" seme. Probabilmente c'è un'istanza che gira intorno a quella (Oop! L'hai trovata mentre stavo scrivendo questo) - e, come sempre, queste cose 'semplici' richiedono solo poche righe per scrivere quando le vuoi.

    
risposta data 12.01.2015 - 06:17
fonte
1

Dopo un altro po 'di scavo finalmente mi è venuto. In effetti, c'è una tale generalizzazione e mi stava fissando per tutto il tempo. La sensazione terribilmente monadica che stavo ottenendo era lì perché c'era davvero una monade, simulata con delle tuple, in agguato nel backgroud.

Per quelli in stato di suspense, è replicateM insieme a Control.Monad.Random (per il mio esempio).

Nota : posterò una risposta più dettagliata quando avrò tempo; volevo solo risolvere la domanda per risparmiare un po 'gli spettatori.

    
risposta data 12.01.2015 - 06:04
fonte

Leggi altre domande sui tag