question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Boxed collections

See original GitHub issue

Description

Is it possible to have code like this:

    | Shape.FSharpList s ->
        s.Accept
          { new IFSharpListVisitor<'T -> V> with
              member __.Visit<'a> () =
                wrap (fun (ts: 'T list) ->
                  ts
                  |> List.map (fun t -> x2V (t.GetType()) t)
                  |> List.toArray
                  |> fun args -> V.ForList(args))
          }

when the list is e.g. string list, but is only known to the caller as obj, which is then reflected over?

…without getting the dreaded exception:

System.InvalidCastException: Unable to cast object of type 'Microsoft.FSharp.Collections.FSharpList`1[System.String]' to type 'Microsoft.FSharp.Collections.FSharpList`1[System.Object]'.
   at Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.UnboxGeneric[T](Object source)
   at Logary.Targets.Stackdriver.Impl.wrap@169-1.Invoke(a inp) /logary/src/targets/Logary.Targets.Stackdriver/Target_Stackdriver.fs:line 169

That is

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
eiriktsarpaliscommented, Mar 22, 2018

It is possible, but you need to use custom lambda types:

type IBoxedLambda =
    abstract InputType : System.Type
    abstract InvokeBoxed : obj -> obj

type MyCustomLambda<'T,'V>(f : 'T -> 'V) =
    interface IBoxedLambda with
       member __.InputType = typeof<'T>
       member __.InvokeBoxed o = f (o :?> 'T) :> obj

You then just replace your wrap function with MyCustomLambda(f) :> IBoxedLambda

0reactions
eiriktsarpaliscommented, Mar 25, 2018

You can define the following

let toJsonUntyped (t:Type) : IBoxedLambda =
    let shape = TypeShape.Create t
    shape.Accept { new ITypeShapeVisitor<IBoxedLambda> with
         member __.Visit<'t> () = toJson<'t>() :> IBoxedLambda }

then in the relevant toJson code:

fun value ->
    match value with
    | null -> Json.Null
    | o -> toJsonUntyped (o.GetType()) . InvokeBoxed o

It is advisable to memoize the generated lambdas, otherwise you’ll end up paying expensive reflection querying logic on every serialization cycle.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Book Box Sets and Movie Box Sets | Barnes & Noble
Explore a curated selection of collectible boxed sets of your favorite series at Barnes & Noble. Shop beautifully packaged box sets and exclusives...
Read more >
Boxed Sets: Movies & TV
Online shopping for Movies & TV from a great selection of Television, Drama, Comedy, Documentary, Action & Adventure, Anime & more at everyday...
Read more >
Teens & YA Book Series Boxed Sets
Explore our list of boxed sets for teens and YA including popular book series like Throne of Glass, Twilight, The Hunger Games and...
Read more >
Boxed Sets
Definitive collector's editions—handsome sets printed on acid-free paper, bound in cloth, and protected by sturdy slipcases designed by leading graphic artists ...
Read more >
Bestselling Boxed Sets!
Shop More Boxed Sets ; Arcturus - The World Mythology - Deluxe Box Collection · The World Mythology - Deluxe Box Collection. Arcturus...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found