urgente una semana rapido peso para necesito meses mes kilos facil dietas dieta como bajar año f# casting

f# - una - ¿Cómo bajar de obj a la opción<obj>?



dietas para bajar 30 kilos en un mes (3)

No estoy seguro de por qué necesita obtener su entrada como obj, pero si su entrada es una Opción <_>, entonces es fácil:

member t.Bind (x : ''a option, rest : obj option -> ''b) = let x = // val x : obj option x |> Option.bind (box >> Some) rest x

Tengo una función que toma un parámetro de tipo objeto y necesita bajarlo a una option<obj> .

member s.Bind(x : obj, rest) = let x = x :?> Option<obj>

Si paso (por ejemplo) una Option<string> como x , la última línea arroja la excepción: No se puede convertir el objeto del tipo ''Microsoft.FSharp.Core.FSharpOption''1 [System.String]'' para escribir ''Microsoft.FSharp .Core.FSharpOption''1 [System.Object] ''.

O bien, si pruebo una prueba de tipo:

member s.Bind(x : obj, rest) = match x with | :? option<obj> as x1 -> ... // Do stuff with x1 | _ -> failwith "Invalid type"

entonces x nunca coincide con la option<obj> .

Para que esto funcione, actualmente tengo que especificar el tipo que contiene la opción (por ejemplo, si la función se pasa una option<string> , y yo downcast el parámetro a que en lugar de la option<obj> , la función funciona.

¿Hay alguna manera de que pueda bajar el parámetro a la option<obj> sin especificar qué tipo contiene la opción? option<#obj> option<_> , la option<#obj> y la option<''a> con los mismos resultados.

A modo de fondo, el parámetro debe ser de tipo obj porque estoy escribiendo una interfaz para una mónada, por lo que Bind necesita vincular valores de diferentes tipos según la mónada que implementa la interfaz. Esta mónada particular es una mónada de continuación, por lo que solo quiere asegurarse de que el parámetro sea Some(x) y not None , luego pase x on a rest. (La razón por la que necesito la interfaz es porque estoy escribiendo un transformador de mónada y necesito una forma de decirle que sus mónadas de parámetros implementan bind y return).

Actualización: Logré solucionar esto subiendo los contenidos de la opción antes de que se convirtiera en un parámetro para esta función, pero aún tengo curiosidad por saber si puedo probar la tecnología o convertir un objeto (o parámetro genérico) en una opción. sin preocuparse por qué tipo contiene la opción (suponiendo, por supuesto, que el elenco es válido, es decir, el objeto realmente es una opción).


No hay ninguna buena manera de resolver este problema actualmente.

El problema es que necesitarás introducir un nuevo parámetro de tipo genérico en la coincidencia de patrones (cuando coincida con la option<''a> ), pero F # solo te permite definir parámetros de tipo genéricos en las declaraciones de funciones. Entonces, tu única solución es usar algunos trucos de Reflexión. Por ejemplo, puede definir un patrón activo que lo oculte:

let (|SomeObj|_|) = let ty = typedefof<option<_>> fun (a:obj) -> let aty = a.GetType() let v = aty.GetProperty("Value") if aty.IsGenericType && aty.GetGenericTypeDefinition() = ty then if a = null then None else Some(v.GetValue(a, [| |])) else None

Esto le dará None o Some containing obj para cualquier tipo de opción:

let bind (x : obj) rest = match x with | SomeObj(x1) -> rest x1 | _ -> failwith "Invalid type" bind(Some 1) (fun n -> 10 * (n :?> int))


Para responder a su última pregunta: puede usar una pequeña variación del código de Tomás si necesita una forma general para verificar las opciones sin valores de boxeo de antemano:

let (|Option|_|) value = if obj.ReferenceEquals(value, null) then None else let typ = value.GetType() if typ.IsGenericType && typ.GetGenericTypeDefinition() = typedefof<option<_>> then let opt : option<_> = (box >> unbox) value Some opt.Value else None //val ( |Option|_| ) : ''a -> ''b option let getValue = function | Option x -> x | _ -> failwith "Not an option" let a1 : int = getValue (Some 42) let a2 : string = getValue (Some "foo") let a3 : string = getValue (Some 42) //InvalidCastException let a4 : int = getValue 42 //Failure("Not an option")