Qual è un buon modo per progettare / strutturare grandi programmi funzionali, specialmente in Haskell?
Ho seguito diversi tutorial (Scrivi a te stesso uno Schema come il mio preferito, con Real World Haskell al secondo posto) - ma la maggior parte dei programmi sono relativamente piccoli e monouso. Inoltre, non considero alcuni di loro particolarmente eleganti (ad esempio, le vaste tabelle di ricerca in WYAS).
Ora voglio scrivere programmi più grandi, con più parti mobili: acquisire dati da una varietà di fonti diverse, pulirli, elaborarli in vari modi, visualizzarli nelle interfacce utente, persistere, comunicare su reti, ecc. Come si potrebbe quale struttura migliore tale codice sia leggibile, gestibile e adattabile alle mutevoli esigenze?
C'è una grande letteratura che affronta queste domande per grandi programmi imperativi orientati agli oggetti. Idee come MVC, modelli di progettazione, ecc. Sono prescrizioni decenti per la realizzazione di obiettivi generali come la separazione delle preoccupazioni e la riusabilità in uno stile OO. Inoltre, i linguaggi imperativi più recenti si prestano a uno stile di refactoring "design as you grow" al quale, secondo la mia opinione da principiante, Haskell sembra meno adatto.
Esiste una letteratura equivalente per Haskell? In che modo lo zoo di strutture di controllo esotiche è disponibile nella programmazione funzionale (monadi, frecce, applicativo, ecc.) Meglio impiegato a questo scopo? Quali migliori pratiche potresti consigliare?
Grazie!
EDIT (questo è un seguito alla risposta di Don Stewart):
@dons menzionato: "Le monadi catturano i progetti architettonici chiave in tipi".
Immagino che la mia domanda sia: come pensare ai progetti architettonici chiave in un linguaggio puramente funzionale?
Considera l'esempio di diversi flussi di dati e diverse fasi di elaborazione. Sono in grado di scrivere parser modulari per i flussi di dati su un insieme di strutture di dati e posso implementare ogni fase di elaborazione come una funzione pura. Le fasi di elaborazione richieste per un dato dipenderanno dal suo valore e da quello di altri. Alcuni passaggi dovrebbero essere seguiti da effetti collaterali come aggiornamenti della GUI o query del database.
Qual è il modo "giusto" per legare i dati e le fasi di analisi in un modo carino? Si potrebbe scrivere una grande funzione che fa la cosa giusta per i vari tipi di dati. Oppure si potrebbe usare una monade per tenere traccia di ciò che è stato elaborato finora e fare in modo che ogni fase di elaborazione ottenga ciò di cui ha bisogno dopo lo stato della monade. Oppure si potrebbe scrivere programmi in gran parte separati e inviare messaggi in giro (questa opzione non mi piace molto).
Le diapositive che ha collegato hanno un proiettile Things we Need: "Idiomi per mappare il design su tipi / funzioni / classi / monadi". Quali sono i modi di dire? :)