Is there an infix version for routine invocation in perl 6? - functional-programming

Say I want to apply an array of functions to an array of objects. Something like this:
my $a = sub ($) { $_ * 2 };
my $b = sub ($) { $_ / 2 };
my #funcs = ($a, $b);
my #ops = #funcs.roll(4);
I could do
say ^10 ».&» #ops;
but .& is a postfix operator; same thing for >>., which could be used for a single function, however. Using
say ^10 Z. #ops;
with . actually being the infix operator for calling a method, yields an error about mistaking it for the concatenation operator. I don't think I have any other option left. Any idea?

You could use the &infix:« o » / &infix:« ∘ » operator, combined with a lambda/closure factory.
sub lambda-factory ( +in ) {
in.map: -> \_ { ->{_} }
}
my #funcs = (
* * 2,
* / 2
);
(#funcs X∘ lambda-factory ^10)».()
# (0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5)
(#funcs «∘» lambda-factory ^10)».()
# [0, 0.5, 4, 1.5, 8, 2.5, 12, 3.5, 16, 4.5]
( (|#funcs xx *) Z∘ lambda-factory ^10 )».()
# (0, 0.5, 4, 1.5, 8, 2.5, 12, 3.5, 16, 4.5)

If you have defined values, you can use the infix operator andthen.
say (^10 »andthen» (* * 2, * / 2).roll(4))

If you roll your own infix equivalent of .& the construct you are trying to create seems to work fine.
$ perl6 -e 'my sub infix:<foo> ($a, $b) { $b($a) }; say ^10 Z[foo] (-> $_ { $_*2 }, -> $_ { $_/2 }).roll(4);'
(0 0.5 1 6)

Related

Remove elements of vector in a loop based on index

Let's say I have a vector, the values are from 1 to 10. I want that if you find 5 and 5 next to each other, remove them together with the next elements.
input
[1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10]
expected output
[1, 2, 3, 4]
This was my attempt. I'm finding index to remove, but borrowing rules are making me stuck.
let mut element = vec![1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10];
for (index, val) in element.iter().enumerate() {
if *val == 5 {
if let Some(next_val) = element.get(index + 1) {
if *next_val == 5 {
//element.drain(index..);
}
}
}
}
Rust is saving you from iterator invalidation (a common source of bugs in other languages). This is an error that usually happens when you try to modify a data structure while concurrently iterating over it. You cannot move on to the (now-deleted) next element after calling element.drain(index..). So you need to add a break after that point to avoid memory unsafety.
In this case just adding break; is sufficient to make the code compile. However, for a more concise, linear solution, take full advantage of the iterators and methods provided by the standard library:
if let Some(index) = element.windows(2).position(|pair| pair[0] == pair[1]) {
element.truncate(index);
}
windows(2) on a slice gives an iterator over subslices of length 2, and the position call returns the index of the first element of that iterator for which the two elements of the slice are equal. (If no such pair exists, position returns None.)
I find that the position closure becomes more obvious with the (currently unstable) array_windows feature:
if let Some(index) = element.array_windows().position(|[x, y]| x == y) {
element.truncate(index);
}
Playground
Related
is it possible to filter on a vector in-place?
You can't do what you want to do because you want to remove some elements from a vector while you are iterating it. And this is a big mistake. Note that removing any elements from a vector invalidates the iterators, hence you will access unexpected locations so rust doesn't allow UBs
You can use something like the following
let mut elements = vec![1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10];
let mut first_repeated_five_index_op = None;
for index in 0..elements.len()-1{
if elements[index] == 5 && elements[index + 1] == 5{
first_repeated_five_index_op = Some(index);
break;
}
}
if let Some(first_repeated_five_index) = first_repeated_five_index_op{
elements.truncate(first_repeated_five_index);
}
println!("{:?}", elements);
See a Demo

filter max of N

Could it be possible to write in FFL a version of filter that stops filtering after the first negative match, i.e. the remaining items are assumed to be positive matches? more generally, a filter.
Example:
removeMaxOf1([1,2,3,4], value>=2)
Expected Result:
[1,3,4]
This seems like something very difficult to write in a pure functional style. Maybe recursion or let could acheive it?
Note: the whole motivation for this question was hypothesizing about micro-optimizations. so performance is very relevant. I am also looking for something that is generally applicable to any data type, not just int.
I have recently added find_index to the engine which allows this to be done easily:
if(n = -1, [], list[:n] + list[n+1:])
where n = find_index(list, value<2)
where list = [1,2,3,4]
find_index will return the index of the first match, or -1 if no match is found. There is also find_index_or_die which returns the index of the first match, asserting if none is found for when you're absolutely certain there is an instance in the list.
You could also implement something like this using recursion:
def filterMaxOf1(list ls, function(list)->bool pred, list result=[]) ->list
base ls = []: result
base not pred(ls[0]): result + ls[1:]
recursive: filterMaxOf1(ls[1:], pred, result + [ls[0]])
Of course recursion can! :D
filterMaxOf1(input, target)
where filterMaxOf1 = def
([int] l, function f) -> [int]
if(size(l) = 0,
[],
if(not f(l[0]),
l[1:],
flatten([
l[0],
recurse(l[1:], f)
])
)
)
where input = [
1, 2, 3, 4, ]
where target = def
(int i) -> bool
i < 2
Some checks:
--> filterOfMax1([1, ]) where filterOfMax1 = [...]
[1]
--> filterOfMax1([2, ]) where filterOfMax1 = [...]
[]
--> filterOfMax1([1, 2, ]) where filterOfMax1 = [...]
[1]
--> filterOfMax1([1, 2, 3, 4, ]) where filterOfMax1 = [...]
[1, 3, 4]
This flavor loses some strong type safety, but is nearer to tail recursion:
filterMaxOf1(input, target)
where filterMaxOf1 = def
([int] l, function f) -> [int]
flatten(filterMaxOf1i(l, f))
where filterMaxOf1i = def
([int] l, function f) -> [any]
if(size(l) = 0,
[],
if(not f(l[0]),
l[1:],
[
l[0],
recurse(l[1:], f)
]
)
)
where input = [
1, 2, 3, 4, ]
where target = def
(int i) -> bool
i < 2

Interleaving Elements of a Prolog list

I am new to Prolog and came across this practice excercise. The question asks to define a predicate
zipper([[List1,List2]], Zippered). //this is two lists within one list.
This predicate should interleave elements of List1 with elements of List2.
For example,
zipper([[1,3,5,7], [2,4,6,8]], Zippered) -> Zippered = [1,2,3,4,5,6,7,8].
zipper([[1,3,5], [2,4,6,7,8]], Zippered) -> Zippered = [1,2,3,4,5,6,7,8].
So far I have a solution for two different list:
zipper ([],[],Z).
zipper([X],[],[X]).
zipper([],[Y],[Y]).
zipper([X|List1],[Y|List2],[X,Y|List]) :- zipper(List1,List2,List).
I am not sure how I can translate this solution for one list. Any suggestion on where I can start would be greatly helpful!
Firstly you should change zipper ([],[],Z). to zipper ([],[],[]).. Then to make it work for one list you could do what mat recommended in the comment or you could change it a little. So my version is:
zipper([],[],[]).
zipper([X,[]],X).
zipper([[],Y],Y).
zipper([[X|List1],[Y|List2]],[X,Y|List]) :- zipper([List1,List2],List).
And for your examples:
?- zipper([[1,3,5,7], [2,4,6,8]], Zippered).
Zippered = [1, 2, 3, 4, 5, 6, 7, 8] ;
Zippered = [1, 2, 3, 4, 5, 6, 7, 8] ;
false.
?- zipper([[1,3,5],[2,4,6,7,8]],Zippered).
Zippered = [1, 2, 3, 4, 5, 6, 7, 8] ;
false.

How to remove\replace big bracket while printing List or array in groovy?

I have to give list of values into in clause of SQL query but while retrieving the values [ ] also come along with data which is not readable by query language.
For example I have list as:
def val = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8))
while doing println(val) output come as [1, 2, 3, 4, 5, 6, 7, 8] but in the query it is needed as: 1, 2, 3, 4, 5, 6, 7, 8
In java this one works as System.out.println(val.toString().replaceAll("[\\[\\]]", "")) but not in groovy. Can't we use collection to remove like this?
Instead of:
def val = new ArrayList(Arrays.asList(1,2,3,4,5,6,7,8))
use:
def val = new ArrayList(Arrays.asList(1,2,3,4,5,6,7,8)).join(', ')
or simply:
def val = [1,2,3,4,5,6,7,8].join(', ')
Try using g-strings and the minus operator:
println "${val}" - '[' - ']'

Iterating Through a Dictionary in Swift

I am a little confused on the answer that Xcode is giving me to this experiment in the Swift Programming Language Guide:
// Use a for-in to iterate through a dictionary (experiment)
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25]
]
var largest = 0
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
}
}
}
largest
I understand that as the dictionary is being transversed, the largest number is being set to the variable, largest. However, I am confused as to why Xcode is saying that largest is being set 5 times, or 1 time, or 3 times, depending on each test.
When looking through the code, I see that it should be set 6 times in "Prime" alone (2, 3, 5, 7, 11, 13). Then it should skip over any numbers in "Fibonacci" since those are all less than the largest, which is currently set to 13 from "Prime". Then, it should be set to 16, and finally 25 in "Square", yielding a total of 8 times.
Am I missing something entirely obvious?
Dictionaries in Swift (and other languages) are not ordered. When you iterate through the dictionary, there's no guarantee that the order will match the initialization order. In this example, Swift processes the "Square" key before the others. You can see this by adding a print statement to the loop. 25 is the 5th element of Square so largest would be set 5 times for the 5 elements in Square and then would stay at 25.
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25]
]
var largest = 0
for (kind, numbers) in interestingNumbers {
println("kind: \(kind)")
for number in numbers {
if number > largest {
largest = number
}
}
}
largest
This prints:
kind: Square
kind: Prime
kind: Fibonacci
let dict : [String : Any] = ["FirstName" : "Maninder" , "LastName" : "Singh" , "Address" : "Chandigarh"]
dict.forEach { print($0) }
Result would be
("FirstName", "Maninder")
("LastName", "Singh")
("Address", "Chandigarh")
This is a user-defined function to iterate through a dictionary:
func findDic(dict: [String: String]) {
for (key, value) in dict {
print("\(key) : \(value)")
}
}
findDic(dict: ["Animal": "Lion", "Bird": "Sparrow"])
// prints…
// Animal : Lion
// Bird : Sparrow
If you want to iterate over all the values:
dict.values.forEach { value in
// print(value)
}
Here is an alternative for that experiment (Swift 3.0). This tells you exactly which kind of number was the largest.
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
var whichKind: String? = nil
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
whichKind = kind
largest = number
}
}
}
print(whichKind)
print(largest)
OUTPUT:
Optional("Square")
25
You can also use values.makeIterator() to iterate over dict values, like this:
for sb in sbItems.values.makeIterator(){
// do something with your sb item..
print(sb)
}
You can also do the iteration like this, in a more swifty style:
sbItems.values.makeIterator().forEach{
// $0 is your dict value..
print($0)
}
sbItems is dict of type [String : NSManagedObject]

Resources