Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

106
Vistas
Implementing an interface with a generic parameter on a F# record

I'm trying to implement the an Microsoft.Extensions.Logging.ILogger (copied below for brevity) on a F# Record

using System;

namespace Microsoft.Extensions.Logging
{
    public interface ILogger
    {
        void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter);
        bool IsEnabled(LogLevel logLevel);
        IDisposable BeginScope<TState>(TState state);
    }
}

This is the record implementation.

  type ILoggerRcd<'TState> = 
    {
      BeginScope : 'TState -> IDisposable
      IsEnabled : LogLevel -> bool
      Log : LogLevel * EventId * 'TState * exn * Func<'TState,exn,string> -> unit
    }
    interface ILogger with
          override this.BeginScope(state : 'TState): IDisposable = 
              this.BeginScope (state)
          override this.IsEnabled(logLevel: LogLevel): bool = 
              this.IsEnabled logLevel
          override this.Log(logLevel: LogLevel, eventId: EventId, state : 'TState, ``exception``: exn, formatter: Func<'TState,exn,string>): unit = 
              this.Log(logLevel, eventId, state, ``exception``, formatter)

However, I'm getting this error on BeginScope: One or more of the explicit class or function type variables for this binding could not be generalized, because they were constrained to other types.

And this error on Log: The generic member 'Log' has been used at a non-uniform instantiation prior to this program point. Consider reordering the members so this member occurs first. Alternatively, specify the full type of the member explicitly, including argument types, return type and any additional generic parameters and constraints.

I've read through a few issues on fsharp compiler itself but nothing seems to be exactly this case I'm hitting. Is this something that can be done?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

The ILogger interface requires that you can log objects of any type, but you're trying to log only those of type 'TState.

Take the signature of BeginScope:

IDisposable BeginScope<TState>(TState state);

See that <TState> bit there? That's a generic parameter. This signature means that every time anybody calls this method, they get to choose a type TState to use with that call.

Again: the caller chooses the generic type, not the implementer.

For example:

let l : ILogger = ...
l.BeginScope 42   // TState = int
l.BeginScope true // TState = bool

This means that your implementation of BeginScope has to be able to work with any type, not just the type with which your ILoggerRcd record was created.

over 4 years ago · Santiago Trujillo Denunciar

0

The problem here is that you are trying to constrain ILogger's 'TState to match the ILoggerRcd's 'TState, but it's not your choice to do that.

To see this, note that a caller of ILogger.BeginScope can pass an int state on one call, and then a string state on another call to the same ILogger instance. Your implementation attempts to prevent this, hence the compiler errors.

The only way I can see around this is to use generic methods in your type instead of a record of functions. I don't think there's any way to do what you want using vanilla F# records.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda