2017-10-18 3 views
1

J'ai une fonction qui traite une liste d'entrées dans un type différent, mais cela n'est pas intéressant en soi.F # Transférer un paramètre dans une fonction d'ordre supérieur ou déclarer sa propre fonction

let testList = [(1,"c");(2,"a");(1,"b")] 

let rec toRel xs = 
    let rec insert (a, b) ys = 
     match ys with 
     | []      -> [(a, [b])] 
     | (a', b')::ys' when a' = a -> (a', b::b')::ys' 
     | y::ys'     -> y::insert (a, b) ys' 
    match xs with 
    | []   -> [] 
    | (a,b)::rest -> insert (a, b) (toRel rest) 

toRel testList //Expected [(1, ["c";"b"]); (2, ["a"])] 

Ceci est bien et bon, et peut être remaniée:

testList |> List.groupBy xs |> List.map (fun (k, v) -> (k, list.map snd v)) 

Ce qui donne le même résultat.

Lorsque j'essaie d'encapsuler ce processus de tuyauterie dans une fonction, je rencontre des problèmes.

let toRelHigherOrder xs = List.groupBy xs |> List.map (fun (k, v) -> (k, list.map snd v)) 

toRelHigherOrder testList 

This expression was expected to have type ''a -> 'b' but here has type '(int * string) list.

Ce qui donne?

+2

normalement la réponse est de remplacer '|>' '>> avec' –

+3

'List.groupBy' est binaire et vous lui donnez seulement un argument, donc vous redirigez une fonction partiellement appliquée, pas une liste. – ildjarn

Répondre

2

Je pense que votre conduite est mauvaise, il devrait être:

testList |> List.groupBy fst |> List.map (fun (k, v) -> (k, List.map snd v)) 

afin que votre fonction doit être:

let f x = x |> List.groupBy fst |> List.map (fun (k, v) -> (k, List.map snd v)) 
+1

Et comme @JohnPalmer mentionné, il pourrait également être 'let f = List.groupBy fst >> List.map (amusant (k, v) -> (k, List.map snd v))', mais cela peut facilement fonctionner dans la restriction de valeur. – ildjarn

+0

Oui, c'est pourquoi je ne l'ai pas mentionné. Bien que la restriction de valeur soit facile à résoudre, dans ce cas, je la résous en la laissant avec un paramètre explicite, comme c'est le cas. – Gustavo

+1

"* mais dans ce cas je le résoudrait en le laissant avec un paramètre explicite, tel qu'il est. *" Bon, c'est ce que je voulais dire. : -] – ildjarn