Ich möchte eine typsichere rekursive Funktion zum Ausflachen von Tupeln erstellen. Allerdings kann ich nicht unter der ersten Rekursion Ebene in Bezug auf die TypsicherheitWie kann ich typesafe rekursive Inline-Funktion für das Reduzieren von Tupeln schreiben
type Flatten = Flatten
with
static member inline ($) (Flatten, (a: 'a, b: 'b)) : 'x list =
List.concat [ Flatten.Flat a; Flatten.Flat b]
static member inline($) (Flatten, (a: 'a, b: 'b, c: 'c)) : 'x list =
List.concat [Flatten.Flat a; Flatten.Flat b; Flatten.Flat c]
static member inline Flat(x: obj) : 'x list =
match x with
| :? Tuple<'a, 'b> as t -> Flatten $ (t.Item1, t.Item2)
| :? Tuple<'a, 'b, 'c> as t ->Flatten $ (t.Item1, t.Item2, t.Item3)
| _ -> [x]
let inline flatten x = Flatten $ x
let a1 = flatten (1, (2, 2, 3), (3,3))
//this compiles
let a2 = flatten (1, (2, 2, 3, 4), (3,3))
// ^but this too
ich einen anderen Ansatz versucht
type Flatten = Flatten
with
static member inline ($) (Flatten, (a: 'a, b: 'b)) = List.concat [ Flat $ a; Flat $ b]
static member inline ($) (Flatten, (a: 'a, b: 'b, c: 'c)) = List.concat [Flat $ a; Flat $ b; Flat $ c]
and Flat = Flat
with
static member inline ($) (Flat, a: 'a) = [a]
static member inline ($) (Flat, x: ('a *'b)) =
let (a, b) = x
List.concat [ Flatten $ a; Flatten $ b]
static member inline($) (Flat, x : ('a * 'b * 'c)) =
let (a, b, c) = x
List.concat [Flatten $ a; Flatten $ b; Flatten $ c]
let inline flatten x = Flatten $ x
let a = flatten (1, 1)
let a1 = flatten (1, 1, 3)
let a2 = flatten (1, 1, (3, 3))
aber ich kann nicht, dass eine Kontrolle zu geben bekommen.
Hat jemand eine Ahnung?
Eine weitere Anforderung
Der Grund, warum ich all das tue, ist zum Teil, weil ich
let a1 = flatten (1, (2, 2, 3), (3,3))
erhalten möchten
val a1 : int list
denn das ist, wenn ich in einem Feed Tupel von Tupel von Int dann sollte das einzige vernünftige Ergebnis einsein. im Moment bekomme ich eine obj list
Int das erste Beispiel ein Kompilierfehler in der zweiten.
Mit freundlichen Grüßen
Sicher können Sie nicht für alle Tupelgrößen. An einem bestimmten Punkt müssen Sie so viele Überladungen wie möglich Tupelgrößen angeben. – Gustavo
Ich würde nur statische Typisierung Garantien verfallen und Reflexion verwenden. – scrwtp
@Gustavo - Da F # nur die Tupelgrößen 1-8 hat und es für größere Tupelgrößen mit verschachtelten Tupeln "vortäuscht", denke ich, dass es tatsächlich möglich ist, dies für alle Tupelgrößen zu schreiben. Ich habe jedoch nie das Bedürfnis verspürt, dies zu tun, da es normalerweise bessere (IMHO) Lösungen für jedes Problem gibt, das dazu führt, dass man Tupel unbekannter Artigkeit glätten will. – rmunn