I think I'm close to what I want, though I suspect I'm not understanding how thaw / TH Region works.
Here is what I'm trying to implement (at least roughly)
modifyPerIndex :: forall t a. Foldable t => t (Tuple Int (a -> a)) -> Array a -> Array a
modifyPerIndex foldableActions array = run do
mutableArray <- thaw array
let actions = fromFoldable foldableActions
foreach actions (\(Tuple index action) -> modify index action mutableArray)
freeze mutableArray
This is sort of how I imagine updateAtIndices works. I suppose I could write modifyPerIndex to use updateAtIndices by reading in the values, applying the (a -> a) and mapping the result into a list of Tuples to be sent to updateAtIndices.
I'm curious how to do it this way though.
In the code above modify returns ST h Boolean, which I'd like to change into ST h Unit. That's where I'm lost. I get that h here is a constraint put on mutable data to stop it from leaving run, what I don't understand is how to use that.
There are a few options. But it has nothing to do with h. You don't have to "use" it for anything, and you don't have to worry about it at all.
First, the most dumb and straightforward approach - just bind the result to an ignored variable and then separately return unit:
foreach actions \(Tuple index action) -> do
_ <- modify index action mutableArray
pure unit
Alternatively, you can use void, which does more or less the same thing under the hood:
foreach actions \(Tuple index action) -> void $ modify index action mutableArray
But I would go straight for for_, which is the same as foreach, but works for any monad (not just ST) and ignores individual iterations' return values:
for_ actions \(Tuple index action) -> modify index action mutableArray
I need a very special (and small) function in Swift 5.
The function will take an arbitrary string as argument, the only thing known about the argument is that it contains at least one of the characters 'a' or 'b'.
The function is only interested in the characters 'a' and 'b', ignoring the others.
If the last found is an 'a', it returns 'a', if is a 'b' it returns 'b'.
For example, let f be this function.
f("aaa") // returns a.
f("a3242avfvabbba54gg") // returns a.
f("abaagdfb") // returns b.
f("479wfwrvfb8709iho") // returns b.
It is obviously easy to write such a function, but I want to know if there is a particularly clean way in Swift 5 using the last API.
I found the last(where:) method of String, but no sample code to make its usage clear. So I am not sure if that is what I want to use.
You are correct that this function can be implemented with last(where:):
func f(_ s: String) -> Character {
return s.last(where: "ab".contains)!
}
Note that I have used ! to force unwrap because you said there always will be an a or b.
I'm trying to create a parser for program. For example,
I entered (what I want)
"(2+3)-4" it will become something like this "(minus, (plus, num 2, num 3),num 4)"
What I've done so far..
"(2+3)-4" I then split it and it becomes list Z = ["(","2","+","3",")","-","4"] then I compared if "-" is a member of Z, if true I append the element "-" into a new list ["-"]
I'm not sure if the way I'm doing is correct, I'm new to Er-lang and struggling quite a lot. If anyone is able to offer me some insight, thanks.
Consider the following, which returns a tuple-based representation of its input:
parse(Expr) ->
Elems = re:split(Expr, "([-+)(])", [{return,list}]),
parse(lists:filter(fun(E) -> E /= [] end, Elems), []).
parse([], [Result]) ->
Result;
parse([], [V2,{op,Op},V1|Tacc]) ->
parse([], [{Op,V1,V2}|Tacc]);
parse(["("|Tail], Acc) ->
parse(Tail, [open|Acc]);
parse([")"|Tail], [Op,open|TAcc]) ->
parse(Tail, [Op|TAcc]);
parse(["+"|Tail], Acc) ->
parse(Tail, [{op,plus}|Acc]);
parse(["-"|Tail], Acc) ->
parse(Tail, [{op,minus}|Acc]);
parse([V2|Tail], [{op,Op},V1|Tacc]) ->
parse(Tail, [{Op,V1,{num,list_to_integer(V2)}}|Tacc]);
parse([Val|Tail], Acc) ->
parse(Tail, [{num,list_to_integer(Val)}|Acc]).
The first function, parse/1, splits the expression along the + and - operators and parentheses, preserving these in the resulting list. It then filters that list to remove empty elements, and passes it with an empty accumulator to parse/2.
The parse/2 function has eight clauses, described below:
The first two handle the case when the parsed input list has been exhausted. The second of these handles the case where multiple elements in the accumulator need to be collapsed into a single tuple consisting of operator and operands.
The next two handle clauses parentheses. When we see an open parenthesis, we push an atom open into the accumulator. Upon seeing the matching close parenthesis, we expect to see an operation tuple and the atom open in the accumulator, and we replace them with just the tuple.
Clauses 5 and 6 handle + and - respectively. Each just pushes a {op,Operator} tuple into the accumulator, where Operator is either the atom plus or the atom minus.
The final two clauses handle values. The first one handles the case where the accumulator holds a value and an op tuple, which gets replaced with a full operation tuple consisting of the atom plus or minus followed by two num tuples each holding integer operands. The last clause just handles plain values.
Putting this in a module p, compiling it, and running it in an Erlang shell yields the following:
1> p:parse("2+3").
{plus,{num,2},{num,3}}
2> p:parse("(2+3)-4").
{minus,{plus,{num,2},{num,3}},{num,4}}
Although I know about splats, still I can't quite grasp the last line from the following code:
class Borrowable extends Decorator
constructor: (#libraryItem) ->
removeBorrower: (borrower) ->
#borrowers[t..t] = [] if ( t = #borrowers.indexOf(borrower) ) > -1
Btw, this code was copied from https://github.com/aksharp/Design-Patterns/blob/master/CoffeeScript/Decorator.coffee
Im assuming this is Destructuring Assignment, still I can't quite get my head around what's it's happening behind the scenes.
Could you help clarify this?
Let's have a closer look at the last line:
#borrowers[t..t] = [] if ( t = #borrowers.indexOf(borrower) ) > -1
I'm not sure if this form counts as Destructuring Assignment, probably it is.
First, it calls #borrowers.indexOf(borrower) to check that borrower is present inside of the #borrowers array and to get it's index.
It's conventional to use borrower in #borrowers form instead of #borrowers.indexOf(borrower) > -1, but in this case we need index of an element as well.
If borrower is present in #borrowers, it gets the part of the #borrowers array between indexes t and t
#borrowers[t..t]
which is the [borrower], and assigns it to the empty array [], thus removing the borrower from #borrowers array.
Here is js-like equivalent of this assignment:
#borrowers.splice t, 1
array = [1,2,3,4]
for num in array
//do something
What is the value of num in the context of the rest of the function? Does num get scoped to the loop?
No, num doesn't get scoped to the loop. As you can see in compiled JS (as #epidemian pointed out) it is current scope variable, so you can access it also in the rest of the function (e.g. rest of the current scope).
But be careful in case of defining function callback inside the loop:
array = [1, 2, 3]
for num in array
setTimeout (() -> console.log num), 1
outputs
3
3
3
To capture current variable inside the callback, you should use do which simply calls the function:
for num in array
do (num) ->
setTimeout (() -> console.log num), 1