Реализация последовательностей последовательностей в F # - PullRequest
3 голосов
/ 09 апреля 2011

Я пытаюсь представить двумерный массив в виде последовательности последовательностей на объекте (чтобы иметь возможность конкретно выполнять Seq.fold (fun x -> Seq.fold (fun ->..) [] x) [] mytype)

Ниже представлена ​​игрушечная программа, которая предоставляет идентичные функциональные возможности.

Из того, что я понимаю, здесь многое происходит, во-первых, IEnumerable имеет неоднозначную перегрузку и требует аннотации типа для явной изоляции, о которой IEnumerable вы говорите.

Но тогда могут возникнуть проблемы с модулем, требующим дополнительной помощи:

type blah =
class
    interface int seq seq with
        member self.GetEnumerator () : System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<(int*int)>> =
                seq{ for i = 0 to 10 do
                        yield seq { for j=0 to 10 do
                                        yield (i,j)} }
end

Есть ли какой-нибудь способ заставить приведенный выше код работать так, как задумано (верните seq<seq<int>>), или я упустил что-то фундаментальное?

Ответы [ 4 ]

4 голосов
/ 09 апреля 2011

Ну, во-первых, GetEnumerator() должен возвращать IEnumerator<T>, а не IEnumerable<T> ...

Это позволит получить пример кода для компиляции.

type blah =
    interface seq<seq<(int * int)>> with
        member self.GetEnumerator () =
            (seq { for i = 0 to 10 do
                    yield seq { for j=0 to 10 do
                                    yield (i,j)} }).GetEnumerator()
    interface System.Collections.IEnumerable with
        member self.GetEnumerator () =
            (self :> seq<seq<(int * int)>>).GetEnumerator() :> System.Collections.IEnumerator
0 голосов
/ 09 апреля 2011
   module Array2D =
      // Converts 2D array 'T[,] into seq<seq<'T>>  
      let toSeq (arr : 'T [,]) =
         let f1,f2 = Array2D.base1 arr , Array2D.base2 arr
         let t1,t2 = Array2D.length1 arr - f1 - 1 , Array2D.length2 arr - f2 - 1
         seq {
           for i in f1 .. t1 do
              yield seq {
                 for j in f2 .. t2 do
                    yield Array2D.get arr i j }}

    let myArray2D : string[,] = array2D [["a1"; "b1"; "c1"]; ["a2"; "b2"; "c2"]]

    printf "%A" (Array2D.toSeq myArray2D)
0 голосов
/ 09 апреля 2011

Что вы действительно хотите сделать?Последовательность seqs редко бывает полезна.Все коллекции являются последовательными, поэтому вы можете просто использовать массив массивов, например,

let myArrayOfArrays = [|
    for i = 0 to 9 do
        yield [|
            for j = 0 to 9 do
                yield (i,j)
            |]
    |]

let sumAllProds = myArrayOfArrays |> Seq.fold (fun st a ->
                             st + (a |> Seq.fold (fun st (x,y) -> st + x*y) 0) ) 0
printfn "%d" sumAllProds

, если это поможет ...

0 голосов
/ 09 апреля 2011

Как насчет:

let toSeqOfSeq (array:array<array<_>>) = array |> Seq.map (fun x -> x :> seq<_>)

Но это работает с массивом массивов, а не с двумерным массивом. Что вы хотите?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...