Ho usato le librerie Scrap Your Boilerplate e Uniplate nel linguaggio di programmazione Haskell e troverei davvero utile quella forma di programmazione generica su unioni discriminate. Esiste una libreria equivalente nel linguaggio di programmazione f #?Scrap Your Boilerplate in f #
11
A
risposta
11
Non che io sappia; senza supporto integrato nel linguaggio/compilatore, mi aspetto che l'unica alternativa sia una versione basata su reflection. (Non so come sia implementato lo Uniplate, vero?
Ecco il codice per una versione basata su riflessione basata sull'esempio della presentazione originale. Non ho pensato profondamente ai suoi limiti, ma era molto più semplice scrivere di quanto avrei immaginato.
type Company = C of Dept list
and Dept = D of Name * Manager * SubUnit list
and SubUnit = | PU of Employee | DU of Dept
and Employee = E of Person * Salary
and Person = P of Name * Address
and Salary = S of float
and Manager = Employee
and Name = string
and Address = string
let data = C [D("Research",E(P("Fred","123 Rose"),S 10.0),
[PU(E(P("Bill","15 Oak"),S 5.0))])]
printfn "%A" data
open Microsoft.FSharp.Reflection
let everywhere<'a,'b>(f:'a->'a, src:'b) = // '
let ft = typeof<'a> // '
let rec traverse (o:obj) =
let ot = o.GetType()
if ft = ot then
f (o :?> 'a) |> box // '
elif FSharpType.IsUnion(ot) then
let info,vals = FSharpValue.GetUnionFields(o, ot)
FSharpValue.MakeUnion(info, vals |> Array.map traverse)
else
o
traverse src :?> 'b // '
let incS (S x) = S(x+1.0)
let newData = everywhere(incS, data)
printfn "%A" newData
La funzione everywhere
attraversa l'intera struttura di un DU arbitraria e applica la funzione f
a ciascun nodo che è il tipo che f
funziona, lasciando tutti gli altri nodi così com'è.
Problemi correlati
- 1. Existentials and Scrap your Boilerplate
- 2. Equivalente Clojure di "Scrap Your Boilerplate" (SYB)
- 3. Scrap Il tuo equivalente Boilerplate in Scala?
- 4. Haskell's Scrap Your Boilerplate (SYB) - applica la trasformazione una sola volta anziché ovunque
- 5. Hacking your own application
- 6. Scrap sito web utilizzando Scrapy
- 7. google maps your timeline api
- 8. documentazione gae-boilerplate
- 9. node.js + best practice boilerplate
- 10. Backbone.Marionette vs Backbone-Boilerplate
- 11. Backbone Boilerplate Template
- 12. Annotazione Boilerplate di AST in Haskell?
- 13. Come posso impostare Yii Boilerplate?
- 14. Haskell ReaderT Env IO boilerplate
- 15. Bootstrap HTML5 Boilerplate e Twitter
- 16. Come riparare l'app Mojolicious-Boilerplate?
- 17. Reagire: evitare boilerplate componente controllato
- 18. Cercapersone dinamico con Nightmare/Electron (page scrap)
- 19. Registra variazioni in F #
- 20. F # ciclo continuo in F #
- 21. Roll Your Own Linked List/Tree in R?
- 22. Come dividere F [A \/B] in (F [A], F [B])
- 23. HTML5 Boilerplate, HTML5 Reimposta convalida CSS
- 24. Java BuilderTestPattern - come evitare il boilerplate?
- 25. in F #
- 26. C# - composizione oggetto - Rimozione Codice Boilerplate
- 27. Minimal, buon cittadino, C# applicazione console boilerplate
- 28. HTML5 Boilerplate .htaccess cache busting non funziona con WordPress
- 29. Web scrap di Python che coinvolge tag HTML con attributi
- 30. Visual Studio e SQL Server Management Studio - Your Pick
Questo è un buon suggerimento, dovrò pensare alle implicazioni delle prestazioni di un tale approccio. In ogni caso, probabilmente non ha importanza per il mio caso particolare. –
re: la tua domanda su come implementare Uniplate la fonte è disponibile su http://community.haskell.org/~ndm/darcs/uniplate/. –
Ho accettato la tua risposta poiché ritengo sia un buon approccio, ma apporto una modifica per farlo funzionare correttamente: Ho sostituito "ft = ot" con "ot.IsSubclassOf (ft)" - altrimenti non riesce a corrispondere quando il tipo di argomento di f, cioè 'a è più generico rispetto all'argomento specifico che viene passato. –