2

I'm experimenting with integration of F# as scripting language and have an issue with FsiEvaluationSession.AddBoundVariable method. Problem is that this method creates variable of actual type of object, but I need to create variable of interface that it implements. I can't find AddBoundVariable<T>(string, T) or any other overload that would allow be do that.

// located in common assembly
type IFoo =
    abstract Foo : unit -> unit

type FooImpl() =
    interface IFoo with
        member _.Foo () = ()

// located in host
session.AddBoundVariable ("foo", Foo())

session.EvalInteraction "foo.Foo()" // throws, `FooImpl` type doesn't have `Foo` method

session.EvalInteraction """
let foo : IFoo = foo
foo.Foo()
""" // throws, `IFoo` not found

Question is: how can I create variable of type that I want?

JL0PD
  • 3,698
  • 2
  • 15
  • 23

1 Answers1

2

You have to explicitly cast the Foo instance to IFoo, so this should work:

session.EvalInteraction """
let foo = foo :> IFoo
foo.Foo()
"""

To avoid the indirection of FSI, you can try this in your compiled code by simply binding foo as normal first:

let foo = FooImpl()
let foo : IFoo = foo    // ERROR: This expression was expected to have type 'IFoo' but here has type 'FooImpl'
let foo = foo :> IFoo   // works fine
foo.Foo()
Brian Berns
  • 15,499
  • 2
  • 30
  • 40
  • The problem was that `session.AddBoundVariable` add variable but doesn't add library to compilation context. I had to explicitly add library with `session.EvalInteraction """#r "CommonLib.dll""""` and then it works. Still thanks! – JL0PD Sep 13 '21 at 02:00
  • That's good to know, but is a different problem from the question you asked. Anyway, I'm glad you were able to figure it out. – Brian Berns Sep 13 '21 at 03:15