Su plancha de caldera de la chatarra en f #
-
02-10-2019 - |
Pregunta
He utilizado el chatarra Su plancha de caldera y bibliotecas Uniplate en el lenguaje de programación Haskell, y que iba a encontrar esa forma de programación genérica sobre los sindicatos discriminados a ser realmente útil. ¿Hay una biblioteca equivalente en el lenguaje de programación C #?
Solución
No, que yo sepa; sin apoyo incorporado a la lengua / compilador, espero que la única alternativa es una versión basada en la reflexión. (No sé cómo Uniplate se implementa -? ¿Verdad)
Este es el código para una versión basada en la reflexión basada en el ejemplo de la presentación original. No he pensado profundamente acerca de sus limitaciones, pero esto era mucho más simple de escritura de lo que hubiera imaginado.
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 función everywhere
atraviesa toda la estructura de un DU arbitraria y aplica el f
función para cada nodo que es el tipo que f
funciona en, dejando todos los demás nodos como está.