문제

The code sorts two input sequences - seq01 and seq02 - on the basis of their timestamp values and returns a sequence that denotes which sequence is to be read for the values to be in order.

For cases where seq02's timestamp value is lesser than seq01's timestamp value we yield a "2" to the sequence being returned, else a "1". These denote whether at that point seq01 is to be taken or seq02 is to be taken for the data to be in order (by timestamp value).

let mergeSeq (seq01:seq<_>)  (seq02:seq<_>) = 
    seq { 
            use iter01 = seq01.GetEnumerator()
            use iter02 = seq02.GetEnumerator() 
            while iter01.MoveNext() do
                let _,_,time01 = iter01.Current
                let _,_,time02 = iter02.Current 
                while time02 < time01 && iter02.MoveNext()  do 
                    yield "2"
                yield "1"
    }

To test it in the FSI created two sequences a and b, a={1;3;5;...} and b={0;2;4;...}. So the expected values for let c = mergeSeq a b would have been {"2","1","2","1"...}. However I am getting this error: error FS0001: The type ''a * 'b * 'c' does not match the type 'int'

EDIT

After correcting:

let mergeSeq (seq01:seq<_>)  (seq02:seq<_>) = 
    seq { 
            use iter01 = seq01.GetEnumerator()
            use iter02 = seq02.GetEnumerator() 
            while iter01.MoveNext() do
                let time01 = iter01.Current
                let time02 = iter02.Current 
                while time02 < time01 && iter02.MoveNext()  do 
                    yield "2"
                yield "1"
    }

After running this, there's another error: call MoveNext. Somehow the iteration is not being performed.

EDIT 2

let mergeRef (seq01:seq<_>) (seq02:seq<_>) = 
    seq{
            use iter01 = seq01.GetEnumerator()
            use iter02 = seq02.GetEnumerator()
            iter01.MoveNext() 
            iter02.MoveNext() 

            let temp01 = ref iter01.Current  //!!using mutable reference
            let temp02 = ref iter02.Current
            
            while iter01.MoveNext() do
                while (iter02.MoveNext()) && ((!temp02) < (!temp01)) do
                    temp02 := iter02.Current
                    yield "2"
                yield "1" 
                temp01 := iter01.Current

            //if seq01 finishes before seq02
            while iter02.MoveNext() do
                yield "2"

       }
도움이 되었습니까?

해결책

After the edit...

You need to call MoveNext on 2 before accessing current. You're not updating time02 as you move through 2 in the inner loop. And you're not checking for the end of sequences properly (e.g. if 2 ends but 1 is going, you'll try to access 2 after the end).

(Is this homework?)

다른 팁

You need to change

let _,_,time01 = iter01.Current
let _,_,time02 = iter02.Current

to

let time01 = iter01.Current
let time02 = iter02.Current

so that the code is type-checked with seq<int>.

I don't understand your intention. If you want to compare each corresponding pair of elements in two sequences, there are more functional solutions:

let mergeSeq seq01 seq02 = 
    Seq.map2 (fun s1 s2 -> if s2 < s1 then "2" else "1") seq01 seq02

If you want to merge two sorted sequences, using GetEnumerator is fine but returning "2" and "1" doesn't make sense to me.

You have written code as if

a={1,1,1;2,2,2;3,3,3...}

just use

            let time01 = iter01.Current
            let time02 = iter02.Current 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top