F#将参数设置为高阶函数或声明自己的函数

时间:2017-10-18 11:02:19

标签: 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

是什么给出了?

1 个答案:

答案 0 :(得分: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))