ein minimales Beispiel einer Beobachtung verfolgt (diese Art von erstaunt mich):Teil Dekonstruktion in Pattern-Matching (F #)
type Vector = V of float*float
// complete unfolding of type is OK
let projX (V (a,_)) = a
// also works
let projX' x =
match x with
| V (a, _) -> a
// BUT:
// partial unfolding is not Ok
let projX'' (V x) = fst x
// consequently also doesn't work
let projX''' x =
match x with
| V y -> fst y
Was ist der Grund dafür, dass es unmöglich entsprechen gegen einen teilweise dekonstruiert Typ macht?
Einige Teil Dekonstruktionen scheinen in Ordnung zu sein:
// Works
let f (x,y) = fst y
EDIT: Ok, verstehe ich jetzt den "technischen" Grund des Verhaltens beschrieben (Vielen Dank für Ihre Antworten & Kommentare). Ich denke jedoch, dass dieses Verhalten sprachlich ein bisschen "unnatürlich" im Vergleich zum Rest der Sprache ist:
"Algebraisch", mir scheint es merkwürdig, einen Typ "t" vom Typ zu unterscheiden "(t) ". Klammern (in diesem Zusammenhang) werden verwendet, um Vorrang zu geben, wie z.B. in "(t * s) * r" vs "t * (s * r)". Auch fsi Antworten entsprechend, ob ich
type Vector = (int * int)
oder
type Vector = int * int
FSI schicken, die Antwort ist immer
Typ Vector = int * int
Gegeben diejenigen Beobachtungen schließt man, dass "int * int" und "(int * int)" genau die gleichen Typen und t bezeichnen hus, dass alle Vorkommen von einem in jedem Code mit dem anderen ersetzt werden könnten (ref. Transparenz) ... was, wie wir gesehen haben, nicht wahr ist.
Weiter scheint es, dass wir, um das vorliegende Verhalten zu erklären, auf "wie ein Code nach der Kompilierung aussieht" zurückgreifen müssen, anstatt auf semantische Eigenschaften der Sprache, die darauf hinweist, dass es einige gibt. Spannungen "zwischen Sprachsemantik und dem, was der Compiler tatsächlich tut.
Versuchen Sie es stattdessen mit 'type Vector = V of (float * float)', damit der Compiler ein tatsächliches Tupel für den Inhalt verwendet. – kvb
es funktioniert! ... aber wie könnte es einen Unterschied machen ... Ich meine Typ Vector = (V von Float) * Float wäre nicht einmal gültig? –
Die Frage ist: bedeutet 'V von x * y '" V enthält ein Tupel von Elementen der Typen x und y "oder" V enthält zwei verschiedene Felder vom Typ x und y "? Wenn Sie das Tupel nicht in Klammern setzen, nimmt der Compiler das letztere an, aber wenn Sie es in Klammern setzen, bedeutet es Ersteres. Diese Unterscheidung ist hauptsächlich wichtig für Interop mit anderen .NET-Sprachen, aber wie Sie gefunden haben, kann es unter bestimmten Umständen auch Auswirkungen auf die Interaktion mit Werten eines solchen Typs in F # haben. – kvb