F#拆分功能 [英] F# Split Function

查看:71
本文介绍了F#拆分功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建合并排序功能,而我的split方法给了我一个值限制错误.我正在使用2个累加参数,这是拆分产生的2个列表,最后将它们打包到一个元组中以供返回.但是,我收到一个值限制错误,我无法弄清楚问题出在哪里.有人有什么想法吗?

I'm building a merge sort function and my split method is giving me a value restriction error. I'm using 2 accumulating parameters, the 2 lists resulting from the split, that I package into a tuple in the end for the return. However I'm getting a value restriction error and I can't figure out what the problem is. Does anyone have any ideas?

let split lst = 
    let a = []
    let b = []
    let ctr = 0
    let rec helper (lst,l1,l2,ctr) =
        match lst with
          | [] -> [] 
          | x::xs -> if ctr%2 = 0 then helper(xs, x::l1, l2, ctr+1)
                    else 
                    helper(xs, l1, x::l2, ctr+1)
    helper (lst, a, b, ctr)
    (a,b)

任何输入表示赞赏.

推荐答案

如您所写,该代码实际上没有任何意义. F#默认使用不可变值,因此您当前编写的函数可以简化为:

The code, as you have written it, doesn't really make sense. F# uses immutable values by default, therefore your function, as it's currently written, can be simplified to this:

let split lst = 
    let a = []
    let b = []
    (a,b)

这可能不是您想要的.实际上,由于绑定是不变的,因此预先声明a, bctr没有任何价值.

This is probably not what you want. In fact, due to immutable bindings, there is no value in predeclaring a, b and ctr.

这里有一个递归函数可以解决这个问题:

Here is a recursive function that will do the trick:

let split lst = 
    let rec helper lst l1 l2 ctr =
        match lst with
        | [] -> l1, l2 // return accumulated lists
        | x::xs -> 
            if ctr%2 = 0 then 
                helper xs (x::l1) l2 (ctr+1) // prepend x to list 1 and increment
            else 
                helper xs l1 (x::l2) (ctr+1) // prepend x to list 2 and increment
    helper lst [] [] 0

除了使用递归函数外,您还可以使用List.fold解决此问题,fold是一个高阶函数,它概括了我们在上面的递归函数中明确描述的累加过程.

Instead of using a recursive function, you could also solve this problem using List.fold, fold is a higher order function which generalises the accumulation process that we described explicitly in the recursive function above.

这种方法更简洁一些,但对于刚开始使用函数式编程的人来说可能不太熟悉,因此我尝试更详细地描述此过程.

This approach is a bit more concise but very likely less familiar to someone new to functional programming, so I've tried to describe this process in more detail.

let split2 lst =
    /// Take a running total of each list and a index*value and return a new 
    /// pair of lists with the supplied value prepended to the correct list
    let splitFolder (l1, l2) (i, x) =
        match i % 2 = 0 with
        |true -> x :: l1, l2 // return list 1 with x prepended and list2
        |false -> l1, x :: l2 // return list 1 and list 2 with x prepended
    lst
    |> List.mapi (fun i x -> i, x) // map list of values to list of index*values
    |> List.fold (splitFolder) ([],[]) // fold over the list using the splitFolder function

这篇关于F#拆分功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆