F# Generic constraint to have one generic type inherit from another
As from the F# spec:
New constraints of the form type :> 'b are solved again as type = 'b.
There are some popular F# language suggestions that aim to solve this, see:
https://github.com/fsharp/fslang-suggestions/issues/255
https://github.com/fsharp/fslang-suggestions/issues/162
Why does mypy ignore a generic-typed variable that contains a type incompatible with the TypeVar?
I think the problem here is that when you're constructing type alias, you're not actually constructing a new type -- you're just giving a nickname or alternate spelling to an existing one.
And if all you're doing is providing an alternative spelling to a type, that means that it it ought to be impossible to add any extra behavior while doing so. That's exactly what's happening here: you're trying to add additional information (your three type constraints) to Iterable, and mypy is ignoring them. There's a note saying basically this at the bottom of the mypy docs on generic type aliases.
The fact that mypy is just silently using your TypeVar without warning that its additional constraints are being ignored feels like a bug, actually. Specifically, it feels like a usability bug: Mypy ought to have raised a warning here and disallowed using anything other then unrestricted typevars inside your type alias.
So what can you do to type your code?
Well, one clean solution would be to not bother creating the Vector
type alias -- or create it, but not worry about constraining what it can be parameterized with.
This means a user can create a Vector[str]
(aka an Iterable[str]
), but that's really no big deal: they'll get a type error the moment they try actually passing it into any function like your dot_product
function that does use type aliases.
A second solution would be to create a custom vector
subclass. If you do so, you'd be creating a new type and so can actually add new constraints -- but you'd no longer be able to pass lists and such directly into your dot_product
classes: you'd need to wrap them in your custom Vector class.
This can be a little clunky, but you may end up drifting to this solution anyways: it gives you the opportunity to add custom methods to your new Vector class, which could perhaps help improve the overall readability of your code, depending on what exactly you're doing.
The third and final solution is to define a custom "Vector" Protocol. This would let us avoid having to wrap our lists in some custom class -- and we're creating a new type so we can add whatever constraints we want. For example:
from typing import Iterable, TypeVar, Iterator, List
from typing_extensions import Protocol
T = TypeVar('T', int, float, complex)
# Note: "class Vector(Protocol[T])" here means the same thing as
# "class Vector(Protocol, Generic[T])".
class Vector(Protocol[T]):
# Any object that implements these three methods with a compatible signature
# is considered to be compatible with "Vector".
def __iter__(self) -> Iterator[T]: ...
def __getitem__(self, idx: int) -> T: ...
def __setitem__(self, idx: int, val: T) -> None: ...
def dot_product(a: Vector[T], b: Vector[T]) -> T:
return sum(x * y for x, y in zip(a, b))
v1: Vector[int] = [] # OK: List[int] is compatible with Vector[int]
v2: Vector[float] = [] # OK: List[float] is compatible with Vector[int]
v3: Vector[str] = [] # Error: Value of type variable "T" of "Vector" cannot be "str"
dot_product(v3, v3) # Error: Value of type variable "T" of "dot_product" cannot be "str"
nums: List[int] = [1, 2, 3]
dot_product(nums, nums) # OK: List[int] is compatible with Vector[int]
The main disadvantage to this approach is that you can't really add any methods with actual logic to your protocol that you can reuse between anything that might be considered a "Vector". (Well, you sort of can, but not in any way that'll be useful in your example).
How to impose generic constraints to the parameters and return values of a function argument of a generic Kotlin function?
This unexpected behavior was caused by a bug in the Kotlin >=1.4
compiler.
This bug can be tracked here: https://youtrack.jetbrains.com/issue/KT-48935.
Is there a constraint that restricts my generic method to numeric types?
This constraint exists in .Net 7.
Check out this .NET Blog post and the actual documentation.
Starting in .NET 7, you can make use of interfaces such as INumber
and IFloatingPoint
to create programs such as:
using System.Numerics;
Console.WriteLine(Sum(1, 2, 3, 4, 5));
Console.WriteLine(Sum(10.541, 2.645));
Console.WriteLine(Sum(1.55f, 5, 9.41f, 7));
static T Sum<T>(params T[] numbers) where T : INumber<T>
{
T result = T.Zero;
foreach (T item in numbers)
{
result += item;
}
return result;
}
INumber
is in the System.Numerics
namespace.
There are also interfaces such as IAdditionOperators
and IComparisonOperators
so you can make use of specific operators generically.
Generics class method taking function parameter of the generic type doesn't work with Void
You can trick the type inference to almost ignore the missing argument like so:
class Test {
static var test2 = new Test2();
static public function main() {
test2.test(passedFunc);
}
static function passedFunc(?unused):Void {
trace("passedFunc");
}
}
class Test2<T> {
public function new():Void {}
public function test(func: T->Void) {
trace("Test2.testFunc(T)");
}
}
Related Topics
Cleanly Handling /Usr/Local/ with Swift Package Manager and Libevent
Swift: Gradient Splits on Rotation
Wkwebview - Update HTML Tags from Swiftui Textfields
Swift: Draw a Semi-Sphere in Mkmapview
How to Remove The Fading Animation on .Ondelete Swiftui
Given a Swift 'Any' Type How to Determine If It's an 'Optional'
Uislider Handle Changes Width on Different Size Ipads
Syntax to Create Dictionary in Swift
Calling Closure Inside Closure
Is It a Good Way to Access Instance Variable with Self? If I Use a Lot
Arkit: How to Tell If User's Face Is Parallel to Camera
How to Properly Map JSON Properties to Model Properties in Realm.Create
Osx/Swift: Call Function at a Specific Date/Time
Query Value Between Two Other Values in Firebase
Swift, Detect Ibeacons on The Background and Send Notifications When in Range
Turn Off Splash Screen When Using Flutterviewcontroller Within Existing Native App
How to Set .Realm File on Realm
When Creating Thread Safe Reads in Swift, Why Is a Variable Create Outside The Concurrent Queue