#interface #f# #types #overriding
#интерфейс #f# #типы #переопределение
Вопрос:
Я пытаюсь представить двумерный массив в виде последовательности последовательностей на объекте (чтобы иметь возможность выполнять Seq.fold (fun x -> Seq.fold (fun ->..) [] x) []
конкретные действия mytype)
Ниже приведена игрушечная программа, которая предоставляет идентичную функциональность.
Из того, что я понимаю, здесь происходит многое, first of IEnumerable
имеет неоднозначную перегрузку и требует аннотации типа, чтобы явно выделить, о чем IEnumerable
вы говорите.
Но тогда также могут возникнуть проблемы с unit, требующие дополнительной помощи:
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
Есть ли какой-нибудь способ заставить приведенный выше код работать по назначению (возвращать a seq<seq<int>>
) или я упускаю что-то фундаментальное?
Комментарии:
1. можно подумать, что кто-то, изучающий FP, не забудет проверить свои подписи типов …. всем спасибо за помощь
Ответ №1:
Ну, во-первых, GetEnumerator()
предполагается, что возвращает IEnumerator<T>
not 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
Ответ №2:
Как насчет:
let toSeqOfSeq (array:array<array<_>>) = array |> Seq.map (fun x -> x :> seq<_>)
Но это работает с массивом массивов, а не с двумерным массивом. Что вы хотите?
Ответ №3:
Что вы на самом деле собираетесь делать? Последовательность последовательностей редко бывает полезной. Все коллекции разделены, поэтому вы можете просто использовать массив массивов, а-ля
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
если это поможет…
Ответ №4:
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)