Sto cercando di imparare il pacchetto pipes
scrivendo la mia funzione sum
e sto diventando perplesso. Mi piacerebbe non utilizzare le funzioni di utilità da Pipes.Prelude
(poiché ha sum
e fold
e altre funzioni che lo rendono banale) e utilizzare solo le informazioni come descritto in Pipes.Tutorial
. Il tutorial non parla dei costruttori di Proxy
, ma se guardo nell'origine di sum
e fold
utilizza quei costruttori e mi chiedo se sia possibile scrivere la mia funzione sum
senza conoscere questi dettagli di basso livello.Come scrivere una funzione "somma" di Haskell Pipes?
Ho problemi a venire a patti con come questa funzione sarebbe in grado di continuare a prendere valori fino a quando ci sono valori disponibili, e quindi in qualche modo restituire tale somma all'utente. Credo che il tipo sarebbe:
sum' :: Monad m => Consumer Int m Int
Mi sembra questo potrebbe funzionare, perché questa funzione potrebbe consumare valori fino a quando non ci sono più, per poi tornare la somma finale. Vorrei usare in questo modo:
mysum <- runEffect $ inputs >-> sum'
Tuttavia, la funzione in Pipes.Prelude
ha la seguente firma invece:
sum :: (Monad m, Num a) => Producer a m() -> m a
quindi credo che questo è il mio primo ostacolo. Perché la funzione sum
accetta un Producer
come argomento anziché utilizzare >->
per connettersi?
FYI ho finito con il seguente dopo la risposta da danidiaz:
sum' = go 0
where
go n p = next p >>= \x -> case x of
Left _ -> return n
Right (_, p') -> go (n + 1) p'
bene il 'sum' nei tubi prende qualcosa che produce * * numeri e li riassume in un'azione monadica ... l'idea è abbastanza simile ai tuoi se ci pensi - anche il pacchetto è progettato in modo che non ti interessi i dettagli ma usi 'fold' e il resto delle primitive fornite;) – Carsten