the following code snippet does not compile:
[<Interface>]
type IEnvironment<'T> =
abstract Service: 'T
type IStringEnvironment = IEnvironment<string>
type IIntEnvironment = IEnvironment<int>
module StringEnvironment =
let get (env: #IStringEnvironment) = env.Service
module IntEnvironment =
let get (env: #IIntEnvironment) = env.Service
module Composition =
let get env =
let a = StringEnvironment.get env
let b = IntEnvironment.get env
a,b
I wonder why?
I have almost the same setup in my code, except that i dont use the IEnvironment interface, but I have different "Environments" for different contextx, e.g. i have the following:
type ILoggerEnvironment =
abstract GetLogger: ILogger
[<Interface>]
type IDateTimeEnvironment =
abstract GetCurrent: DateTime
and then the Composition seems to work.
I tried different solutions, writing all functions as inline, but the compiler expects the type of the first usage of env to be the type (even with the prepended #, before the parameter type).
an instance of
envcan only be eitherIEnvironment<string>orIEnvironment<int>it can not be both at the same time.As I don't know what is your final goal I cannot give recommendations, but normally if you want to work with different kinds of underling values you can unify them with Discriminated Unions (DU) like this:
Still an instance of
Envwill only be eitherStrorIntso the composition you are trying to do does not hold.