使用自定义比较功能构建列表相等?

时间:2011-03-29 06:24:28

标签: f#

是否有内置功能执行以下操作?

let rec listsEqual xl yl f =
    match xl, yl with
    | [], [] -> true
    | [], _ | _, [] -> false
    | xh::xt, yh::yt -> if f xh yh then listsEqual xt yt f else false

更新,进一步详细说明,一般来说,有没有办法进行结构比较,但使用自定义比较功能?

2 个答案:

答案 0 :(得分:3)

List.forall2 : (('a -> 'b -> bool) -> 'a list -> 'b list -> bool)

但是在列表之前需要f。你可以像这样创建你的函数:

let listsEqual x y f =
    if List.length x = List.length y then
        List.forall2 f x y
    else
        false

请记住List.forall2假设长度相同。

答案 1 :(得分:2)

关于Seq.compareWith,您写道:

  

不完全,两个问题1)期待   两个序列属于同一类型,2)   不会短路

2)错了,这个功能确实是一个法庭回路。 1)是真的。从F#库中获取Seq.compareWith,修改(或删除)类型注释,它将适用于不同类型的序列。

[<CompiledName("CompareWith")>]
let compareWith (f:'T1 -> 'T2 -> int) (source1 : seq<'T1>) (source2: seq<'T2>) =
            //checkNonNull "source1" source1
            //checkNonNull "source2" source2
            use e1 = source1.GetEnumerator()
            use e2 = source2.GetEnumerator()
            let rec go () = 
                let e1ok = e1.MoveNext() 
                let e2ok = e2.MoveNext() 
                let c = (if e1ok = e2ok then 0 else if e1ok then 1 else -1) 
                if c <> 0 then c else
                if not e1ok || not e2ok then 0 
                else
                    let c = f e1.Current e2.Current 
                    if c <> 0 then c else
                    go ()
            go()

现在,您可以向fsbugs(@ microsoft.com)发送电子邮件,并要求他们在下一个F#版本中删除类型约束。