Operatore di differenza dell'elenco Haskell in F#
-
09-06-2019 - |
Domanda
Esiste un operatore equivalente all'operatore di differenza di lista di Haskell \\
in Fa#?
Soluzione
È stato rimbalzato, eppure credo che valga la pena scriverne qui la realizzazione ( /-/ )
(la versione F# di Haskell \\
):
let flip f x y = f y x
let rec delete x = function
| [] -> []
| h :: t when x = h -> t
| h :: t -> h :: delete x t
let inline ( /-/ ) xs ys = List.fold (flip delete) xs ys
Funzionerà come quello di Haskell \\
, affinché (xs @ ys) /-/ xs = ys
.Per esempio: (7 :: [1 .. 5] @ [5 .. 11]) /-/ [4 .. 7]
valuta in [1; 2; 3; 5; 7; 8; 9; 10; 11]
.
Altri suggerimenti
No...Basta scriverlo e renderlo un operatore infisso, utilizzando l'insieme di caratteri speciali.Barra rovesciata (\
) non è nell'elenco seguente, quindi non funzionerà come operatore infisso.Vedi il Manuale:
infisso-op :=
or || & && <OP >OP $OP = |OP &OP ^OP :: -OP +OP *OP /OP %OP **OP
prefisso-op :=
!OP ?OP ~OP -OP +OP % %% & &&
Filtra gli elementi dall'insieme del sottraendo:
let ( /-/ ) xs ys =
let ySet = set ys
let notInYSet x = not <| Set.contains x ySet
List.filter notInYSet xs
Sto usando questo:
let (/-/) l1 l2 = List.filter (fun i -> not <| List.exists ((=) i) l2) l1
Se qualcuno vede un problema, me lo faccia sapere.
È per gli elenchi, quindi potrebbero esserci duplicati nel risultato.Per esempio:
[1;1;2] /-/ [2;3] would be eq to [1;1]
Supponendo che tu voglia davvero la differenza di insieme convenzionale piuttosto che la strana sottrazione multiinsieme ordinata ma non ordinata che Haskell apparentemente fornisce, converti semplicemente gli elenchi in insiemi usando il metodo integrato set
funzione e quindi utilizzare il built-in -
operatore per calcolare la differenza di insieme:
set xs - set ys
Per esempio:
> set [1..5] - set [2..4];;
val it : Set<int> = seq [1; 5]