Um eine Erklärung zu dem von ChaosPandion geschrieben Code hinzufügen, das Problem mit F # Funktionen wie abs
ist, dass sie mit beliebigen numerischen Typs arbeiten können. Es gibt keine Möglichkeit, dies auszudrücken, nur mit F # /. NET-Generics - die einzigen unterstützten Einschränkungen sind, dass Typ Parameter implementiert eine bestimmte Schnittstelle oder hat einen Konstruktor, aber es gibt keine Einschränkung für numerische Typen.
Also, F # unterstützt auch statische Einschränkungen (der Typ-Parameter ist ^a
anstelle der üblichen 'a
) und diese werden bei der Kompilierung verarbeitet inlining verwenden (dies erklärt auch, warum die Funktion inline
sein). Sie können Sie eigene Funktion mit statischen Einschränkungen schreiben von integrierten Funktionen von LanguagePrimitives
verwendet, die viele nützliche Funktionen, die einige Einschränkungen erfordern:
> let inline half (num: ^a) : ^a =
LanguagePrimitives.DivideByInt< (^a) > num 2
;;
val inline half : ^a -> ^a
when ^a : (static member DivideByInt : ^a * int -> ^a)
> half 42.0;;
val it : float = 21.0
> half 42.0f;;
val it : float32 = 21.0f
Beachten Sie, dass Einschränkungen abgeleitet werden - DivideByInt
erfordert, dass der Typ DivideByInt
Mitglied hat, so Unsere Funktion erfordert das gleiche (und es funktioniert mit Ihrem eigenen Typ, wenn es auch dieses Mitglied hat, was sehr nützlich ist!).
Zusätzlich dazu, die Umsetzung der abs
verwendet zwei weitere Tricks, die nur in der F # Bibliothek erlaubt sind - es gibt verschiedenen Code (zu verwenden, wenn inlining) für verschiedene Arten (mit when ^a:int = ....
) und einem Rückfall Fall der verwendet Abs
Mitglied, so dass es mit jedem explizit aufgeführten Typ oder einem Typ mit Abs
Mitglied funktioniert. Ein weiterer Trick ist die -Funktion, die "den Typ ändert", aber keinen Code enthält - der einzige Zweck ist die Überprüfung des Codetyps, aber dies könnte sehr unsicher sein - daher wird dies nur in F # -Bibliotheken verwendet.
Sie müssen nicht X mit 0 vergleichen, um seinen absoluten Wert zu finden - Sie können es mit -X vergleichen. – Simon
@Simon scheint ein guter Punkt. ABER, deine Methode ist nicht korrekt. Betrachte x = -2147483648. –
ja, guter Punkt - obwohl ich vermute, dass Sie die gleiche Ausnahme bekommen würde, versuchen zu bewerten -X in diesem Fall als abs() sollte sowieso werfen. – Simon