I would like to define a generic function to extract keys from a map, something like this:
public list[K] keys(map[K,V] aMap) {
return [ key | key:val <- aMap ];
}
Although no syntax error is given, this does not work. Is there a way to do it?
You can define this as
public list[&K] keys(map[&K,&V] aMap) {
return [ k | k <- aMap ];
}
Note that the keys are unordered, so it may make more sense to return them as a set instead of as a list. You can also always get the keys or values out as sets directly by projecting them out of the map, using either
aMap<0>
for the set of keys or
aMap<1>
for the set of values. Finally, the Set module contains a toList function, so you could do this in one line as
toList(aMap<0>)
which will give you the same result as calling the keys function.
Related
If I have a object like this:
class MyClass<K>{...
How I could check type of K? If was a variable was easy,
ex:
(myVar is Object)... //true | false
But in my case, this dont works:
(K is Object) // awalys false
You want == here. Using is is for comparing the type of variable, not a literal type.
This will only check if K is actually Object if you use K == Object. If you pass K as int for instance, it will not be considered to be an Object.
I recommend not using == for comparison of Type objects. It only checks exact equality, which might be useful in a few situations, but in plenty of situations you do want a subtype check.
You can get that subtype check using a helper function like:
bool isSubtype<S, T>() => <S>[] is List<T>;
Then you can check either isSubtype<K, Object> to check if K is a subtype of Object (which is true for everything except Null and types equivalent to Object?, but that can also be checked like null is! K), or isSubtype<Object, K> to check whether K is a supertype of Object.
It has the advantage that you can compare to any type, not just types you can write literals for. For example K == List only works for List<dynamic>. If you need to check whether K is a List<int>, you can do isSubtype<K, List<int>>.
You can get equivalence of types (mutual subtype), without requiring them to be the same type, by doing isSubtype in both directions. For example isSubtype<Object?, dynamic>() and isSubtype<dynamic, Object?>() are both true, but if K is Object? then K == dynamic is false.
I'm using a MultiMap from the quiver package. I'm trying to populate the map with 2 lists like I would with an ordinary map:
final keys = myMap.keys.toList();
final values = myMap.values.toList();
for (var i = 0; i < values.length; i++) {
map[values[i]] = itemSpit[I];
}
However the for loop doesn't compile: value
The operator '[]=' isn't defined for the type 'Multimap<dynamic, dynamic>'.
How can I add the lists to the multimap
Dart has two versions of the square brackets operator; one for reading (operator []) and one for writing (operator []=). Multimap providers operator [] but does not provide operator []=. Presumably this is because it would be unclear to readers whether multimap[key] = value intends to add a new value or to replace the existing values.
Instead, Multimap provides add and addValues methods for adding values. (Replacing requires explicitly calling removeAll first.)
I have this function where I remove symmetrics pairs from a list relation, works fine but I was curious if it would be possible to rewrite this to a list comprehension.
lrel[str,str] newClonePairs = [];
for (tuple[str L, str R] pair <- clonePairs) {
if (<pair.R, pair.L> notin newClonePairs) {
newClonePairs += pair;
}
}
return newClonePairs;
I got this far (see code below), but how do you then write the notin part? Is there some kind of keyword which can be used to refer to the current list?
return [pair | tuple[tuple[node,loc] L,tuple[node,loc] R] pair <- clonePairs, <pair.R, pair.L> notin thisCurrentList];
The list you are generating can not be referred to during a list comprehension. With a reducer you could, but I don't think it would be very fast.
How about this one:
[ <L, R> | [*_, <L,R>, *post] := clonePairs, <R,L> notin post ]
It will loop through all <L,R> pairs, and add only the ones which are not found in the rest of the list.
It works via "list matching". A list pattern can contain variables with a * in front which will match a sub-list of any length (including the empty list). Such a match is usually not unique (for example above the <L,R> in the middle can be anywhere in the list because *_ and *post can be of any length). If a list pattern can match a list in many ways, then it becomes a generator and the := will loop through all the matches from left to right similar to the behaviour of <-. See also: http://tutor.rascal-mpl.org/Rascal/Rascal.html#/Rascal/Patterns/Abstract/List/List.html
I was curious to know if one could define a data type that we know, should be a tuple, but whose length (or number of elements is indeterminable) currently. The application is as follows:
//I want to declare a data type, one of whose argument is a tuple,
public data MyType=fromListCartesianProduct(tuple<?> product)
//Later I want to instantiate a MyType data by using taking List-CartesianProduct
//instantiate some MyType data
foreach(aTuple in [1,2,3]*["a","b"])
someArr[i]=fromListCartesianProduct(aTuple)
The salient observation is that the number of elements in aTuple is indeterminable while declaring "MyType". Can I still declare such a type in a rascal script?
As an alternate, I would declare MyType as:
public data MyType=fromListCartesianProduct(list[] product)
and convert each tuple from taking the cartesian product into a list before constructing the specific instances. For reasons of clarity and others, I would like to define MyType as I previously did.
In principe the answer is no. Tuples have fixed length and we do not (yet) have row polymorphism.
Having said that, data constructors do support different kinds of polymorphism which might help:
row polymorphism using keyword parameters, you can always add more keyword parameters to a data-type, as in
data MyType = myCons(int j = 0); // initial decl
data MyType(int k = 1); // extension with another field
overloading, you can always add more constructors with more parameters
data MyType = f(int i); // initial declaration
data MyType = f(int i, int j); // overloaded declaration with more fields
You might use the make function from Type to dynamically construct such constructors based on argument lists. At the risk of run-time type exceptions of course.
Another way of dealing with data of unpredictable type is to go up one level in the type hierarchy (let it be value), and later pattern match your way out again:
list[value] myListRelationOfUnknownType = ...;
for (<int i, int j> <- myListRelationOfUnknownType)
println("printing only pairs of ints: <i> - <j>");
for (<int i, int j, int k> <- myListRelationOfUnknownType)
println("printing only the triples of ints: <i> - <j> - <k>");
That's a statically more safe way.
I'm just starting with F# and I want to iterate over a dictionary, getting the keys and values.
So in C#, I'd put:
IDictionary resultSet = test.GetResults;
foreach (DictionaryEntry de in resultSet)
{
Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value);
}
I can't seem to find a way to do this in F# (not one that compiles anyway).
Could anybody please suggest the equivalent code in F#?
Cheers,
Crush
What is the type of your dictionary?
If it is non-generic IDictionary as your code snippet suggests, then try the following (In F#, for doesn't implicitly insert conversions, so you need to add Seq.cast<> to get a typed collection that you can easily work with):
for entry in dict |> Seq.cast<DictionaryEntry> do
// use 'entry.Value' and 'entry.Key' here
If you are using generic IDictionary<'K, 'V> then you don't need the call to Seq.cast (if you have any control over the library, this is better than the previous option):
for entry in dict do
// use 'entry.Value' and 'entry.Key' here
If you're using immutable F# Map<'K, 'V> type (which is the best type to use if you're writing functional code in F#) then you can use the solution by Pavel or you can use for loop together with the KeyValue active pattern like this:
for KeyValue(k, v) in dict do
// 'k' is the key, 'v' is the value
In both of the cases, you can use either for or various iter functions. If you need to perform something with side-effects then I would prefer for loop (and this is not the first answer where I am mentioning this :-)), because this is a language construct designed for this purpose. For functional processing you can use various functions like Seq.filter etc..
resultSet |> Map.iter (fun key value ->
printf "Key = %A, Value = %A\n" key value)
(This is a shorter answer than Tomas' one, going to the point.) Dictionaries are mutable, in F# it's more natural to use Maps (immutable). So if you're dealing with map: Map<K,V>, iterate through it this way:
for KeyValue(key,value) in map do
DoStuff key value