válida usbwebserver tiempo sua solucionar s10 run procedimiento mendeleyplugin llamada invalid error ejecucion argumento argument f# type-inference value-restriction

f# - usbwebserver - solucionar runtime error 5 invalid procedure call or argument



Entendiendo los errores de restricción de valor F# (3)

No entiendo cómo funciona la restricción de valor en F #. He leído la explicación en el wiki , así como la documentación de MSDN . Lo que no entiendo es:

  1. Por qué, por ejemplo, esto me da un error de restricción de valor (tomado de this pregunta):

    let toleq (e:float<_>) a b = (abs ( a - b ) ) < e

    Pero esto no:

    let toleq e (a:float<_>) b = (abs ( a - b ) ) < e

  2. Esto está generalizado de acuerdo ...

    let is_bigger a b = a < b

    pero esto no es (se especifica como int):

    let add a b = a + b

  3. Por qué las funciones con parámetros implícitos generan una restricción de valor:

    esta:

    let item_count = List.fold (fun acc _ -> 1 + acc) 0

    vs esto:

    let item_count l = List.fold (fun acc _ -> 1 + acc) 0 l

    (Tenga en cuenta que si utilizo esta función en un fragmento de código, el error de VR desaparecerá, pero luego la función se especificará para el tipo para el que la usé, y quiero que se generalice)

¿Como funciona?

(Estoy usando el último F #, v1.9.6.16)


EDITAR

La información mejor / reciente está aquí: Mantener la función parcialmente aplicada genérica

(original abajo)

Creo que una cosa pragmática aquí es no tratar de entender esto demasiado profundamente, sino más bien conocer un par de estrategias generales para superar la realidad virtual y continuar con su trabajo. Es un poco una respuesta de "extinción", pero no estoy seguro de que tenga sentido dedicar tiempo a comprender las intracatidades del sistema de tipo F # (que continúa cambiando de maneras menores de lanzamiento a lanzamiento) aquí.

Las dos estrategias principales que yo recomendaría son estas. Primero, si está definiendo un valor con un tipo de función (escriba con una flecha ''->''), asegúrese de que sea una función sintáctica haciendo eta-conversion :

// function that looks like a value, problem let tupleList = List.map (fun x -> x,x) // make it a syntactic function by adding argument to both sides let tupleList l = List.map (fun x -> x,x) l

En segundo lugar, si aún encuentra problemas de VR / generalización, especifique la firma de tipo completa para decir lo que quiere (y luego ''retroceder'' cuando F # lo permita):

// below has a problem... let toleq (e:float<_>) a b = (abs ( a - b ) ) < e // so be fully explicit, get it working... let toleq<[<Measure>]''u> (e:float<''u>) (a:float<''u>) (b:float<''u>) : bool = (abs ( a - b ) ) < e // then can experiment with removing annotations one-by-one... let toleq<[<Measure>]''u> e (a:float<''u>) b = (abs ( a - b ) ) < e

Creo que esas dos estrategias son el mejor consejo pragmático. Dicho esto, aquí está mi intento de responder a sus preguntas específicas.

  1. No lo sé.

  2. ''>'' es una función totalmente genérica (''a ->'' a -> bool) que funciona para todos los tipos, y por lo tanto is_bigger generaliza. Por otro lado, ''+'' es una función ''en línea'' que funciona en un puñado de tipos primitivos y en una cierta clase de otros tipos; solo se puede generalizar dentro de otras funciones ''en línea'', de lo contrario se debe fijar a un tipo específico (o por defecto a ''int''). (El método ''en línea'' del polimorfismo ad-hoc es cómo los operadores matemáticos en F # superan la falta de "clases de tipo").

  3. Este es el problema de la ''función sintáctica'' que mencioné anteriormente; ''vamos a compilar en campos / propiedades que, a diferencia de las funciones, no pueden ser genéricas. Así que si quieres que sea genérico, hazlo una función. (Vea también esta pregunta para otra excepción a esta regla.)


Nadie, incluidas las personas del equipo de F #, conoce la respuesta a esta pregunta de manera significativa.

El sistema de inferencia de tipo F # es exactamente como la gramática VB6 en el sentido de que el compilador define la verdad.

Desafortunado, pero cierto.


Se introdujo la restricción de valor para abordar algunos problemas con el polimorfismo en presencia de efectos secundarios. F # hereda esto de OCaml, y creo que existe una restricción de valor en todas las variantes de ML. Aquí hay few links more para que lea, además de los enlaces que citó. Ya que Haskell es puro, no está sujeto a esta restricción.

En cuanto a sus preguntas, creo que la pregunta 3 está verdaderamente relacionada con la restricción de valor, mientras que las dos primeras no lo están.