I have not looked at the link you sent, but a quick sniff, maybe this helps?

[link:stackoverflow.com]

By on 10/15/2010 5:59 PM ()

Wow, thanks. I can't believe I didn't find that.

I haven't had time to try it yet, but it is certainly the right question, and looks like the right answer as well.

Many thanks.

By on 10/15/2010 11:39 PM ()

I got around to trying this today ... I had to use "IsAssignableFrom" rather then "IsSubclassOf" in the type test. I'm not sure if this will always work correctly in F#, however.

In case anyone is interested, my code is below. I'm a complete F# beginner, and I'm not sure if this is the most appropriate way to do it, but it works in the simple scenarios I've tested.

(EDIT: not sure why initial whitespace is being stripped ...)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
open Microsoft.FSharp.Reflection

let private attempt f (o:obj) = 

  let tType = typeof<'b>

  let oType = o.GetType ()

  if tType.IsAssignableFrom oType

  then Some (f (o :?> 'b))

  else None

let rec private processTerm f onSuccess onUnion onAtom (o : obj) = 

  match attempt f o with

  | Some b -> onSuccess b

  | None   -> let oType = o.GetType ()

              if FSharpType.IsUnion oType

              then let info, vals = FSharpValue.GetUnionFields (o, oType)

                   onUnion info vals

              else onAtom

let everywhere (f : 'a -> 'a) (b : 'b) = 

  let rec everywhere' o = 

    o |> processTerm f box (fun info vals -> FSharpValue.MakeUnion (info, vals |> Array.map everywhere')) o 

  everywhere' (box b) :?> 'b

let query (f : 'a -> 'q) (combine : 'aggregate -> 'q -> 'aggregate) (initial : 'aggregate) (b : 'b) = 

  let rec query' agg o = 

    o |> processTerm f (fun q -> combine agg q) (fun _ -> Array.fold query' agg) agg

  query' initial (box b)
By on 10/17/2010 9:47 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper