Operador de diferencia de lista de Haskell en F#
-
09-06-2019 - |
Pregunta
¿Existe un operador equivalente al operador de diferencia de lista de Haskell? \\
en fa#?
Solución
Fue rechazado, pero creo que vale la pena escribir aquí la implementación de ( /-/ )
(la versión F# de 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
Esto funcionará como el de Haskell. \\
, de modo que (xs @ ys) /-/ xs = ys
.Por ejemplo: (7 :: [1 .. 5] @ [5 .. 11]) /-/ [4 .. 7]
evalúa en [1; 2; 3; 5; 7; 8; 9; 10; 11]
.
Otros consejos
No...Simplemente escríbalo y conviértalo en un operador infijo, utilizando el conjunto de caracteres especiales.Barra invertida (\
) no está en la lista siguiente, por lo que no funcionará como operador infijo.Ver el manual:
operación infija :=
or || & && <OP >OP $OP = |OP &OP ^OP :: -OP +OP *OP /OP %OP **OP
operación de prefijo :=
!OP ?OP ~OP -OP +OP % %% & &&
Filtrar elementos del conjunto del sustraendo:
let ( /-/ ) xs ys =
let ySet = set ys
let notInYSet x = not <| Set.contains x ySet
List.filter notInYSet xs
Estoy usando esto:
let (/-/) l1 l2 = List.filter (fun i -> not <| List.exists ((=) i) l2) l1
Si alguien ve un problema, hágamelo saber.
Es para listas, por lo que podría haber duplicados en el resultado.Por ejemplo:
[1;1;2] /-/ [2;3] would be eq to [1;1]
Suponiendo que realmente desea una diferencia de conjuntos convencional en lugar de la extraña resta de conjuntos múltiples ordenados pero sin clasificar que aparentemente proporciona Haskell, simplemente convierta las listas en conjuntos usando el método incorporado set
función y luego usar el incorporado -
operador para calcular la diferencia establecida:
set xs - set ys
Por ejemplo:
> set [1..5] - set [2..4];;
val it : Set<int> = seq [1; 5]