Data la seguente tipo e funzione membroCome si fa un applicativo in F #?
type Result<'TSuccess, 'TError> =
| Success of 'TSuccess
| Error of 'TError list
with
member this.apply fn =
match (fn, this) with
| Success(f), Success(x) -> Success(f x)
| Error(e), Success(_) -> Error(e)
| Success(_), Error(e) -> Error(e)
| Error(e1), Error(e2) -> Error(List.concat [e1;e2])
e la seguente funzione inline
let inline (<*>) (f: ^A) (t:^A) =
let apply' = (^A : (member apply : ^A -> ^A) (t, f))
apply'
E questo sito chiamata
let y() = Success (fun x -> x + 1) <*> (Success 3)
ottengo il seguente errore
let y() = Success (fun x -> x + 1) <*> (Success 3);;
-----------^^^^^^^^^^^^^^^^^^^^^^^^
/Users/robkuz/stdin(473,12): error FS0001: Type constraint mismatch.
The type
Result<'a,'c>
is not compatible with type
Result<('a -> 'b),'c>
The resulting type would be infinite when unifying ''a' and ''a -> 'b'
Questa intera faccenda è un tentativo di emulare Haskells applicativo e la firma dovrebbe essere
(<*>) :: forall f a b. Apply f => f (a -> b) -> f a -> f b
ma io non quanto ne sappia non c'è modo per esprimere che in F #
Tutte le idee su come fare che questo accada?
La soluzione fornita da @Thomas è OK per il tuo caso, ma si noti che non funzionerà con tipi primitivi (elenco, array, opzione) e non funzionerà automaticamente con nessuna monade. Ecco una [soluzione più completa] (https://github.com/gmpl/FsControl/blob/master/FsControl.Core/Functor.fs#L133). – Gustavo