2017-10-18 3 views
1

入力リストを別の型に処理する関数がありますが、それ自体は面白いことではありません。F#高次関数にパラメータをパイプする、または独自の関数を宣言する

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"])] 

これはよく良好であり、にリファクタリングすることができます。同じ結果を与える

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

このパイピングプロセスを関数にカプセル化しようとすると、問題が発生します。

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

何がありますか?

+2

通常答えは '置き換えることです|' >> ' –

+3

と'> 'List.groupBy'はバイナリであり、あなたはただ一つの引数しか与えていないので、リストではなく、部分的に適用された関数をパイプで渡しています。 – ildjarn

答えて

2

私はあなたのパイプが間違っていると思うが、それは次のようになります。

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

ので、あなたの関数は次のようになります。

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

@ JohnPalmerが言及したように、 'let f = List.groupBy fst >> List.map(fun(k、v) - >(k、List.map snd v))'でも可能ですが、値の制限に入れる。 – ildjarn

+0

はい、私はそれに言及しなかったのです。値の制限は簡単に解決できますが、この場合は明示的なパラメータをそのままにして解決します。 – Gustavo

+1

"*しかし、この場合は明示的なパラメータをそのまま残して解決します。*"そうです、それは私が意味するものです。 : - ] – ildjarn

関連する問題