Lua - Combining two variables - lua

What I am trying to do is create a new variable (let's call it 'C') from adding a string ('Apple') to another variable ('84').
How do I do this?
Example
A = 'Apple'
B = 84
C = 'Apple(84)'

local C = string.format("%s(%i)", A, B)
See the reference for more information on string.format
or, in simple cases like that, you can also just do
local C = A .. "(" .. tostring(B) .. ")"

Related

Type inference F# - how to generate fresh variables?

i'm trying to develop the algorithm W in f# for type inference, but i would like to understand how to write the function for generating fresh variables properly.
Actually my function is
let counter = ref -1
let generate_fresh_variable () : string =
let list_variables = ['a' .. 'z'] |> List.map string
counter.Value <- !counter + 1
list_variables.Item(!counter)
but i'm not satisfy with this solution, someone can give me other better ideas?
If you really want to do this with an impure function, I would write it like this:
let mutable counter = -1
let generate_fresh_variable () =
counter <- counter + 1
counter + int 'a'
|> char
|> string
Notes:
Reference cells are obsolete. If you need impurity, use mutable variables instead. (Alternatively, if you really want to stick with a reference cell, the canonical way to update it is with :=, rather than assigning directly to the underlying Value.)
There's no need to maintain a list of potential variable names (and there's especially no need to rebuild the entire list each time you generate a fresh variable).
What happens if you need more than 26 variables?
If you wanted to use some more sophisticated F# tricks, you could create an inifinte sequence of names using a sequence expression (which makes it very easy to handle the looping and dealing with >26 names):
let names = seq {
for i in Seq.initInfinite id do
for c in 'a' .. 'z' do
if i = 0 then yield string c
else yield string c + string i }
A function to get the fresh name would then pick the next name from the sequence. You need to do this using the underlying enumerator. Another nice trick is to hide the state in a local variable and return a function using lambda:
let freshName =
let en = names.GetEnumerator()
fun () ->
ignore(en.MoveNext())
en.Current
Then just call freshName() as many times as you need.

How can I call bind on a computation expression without the let keyword?

Say I have this:
MyComputationExpression {
let! addr = Salesrecord.Address
let! name = Salesrecord.Name
return (name + " " + addr)
}
Is there any way to "unwrap" (call the bind method on) the address and name on the fly? Sort of like:
MyComputationExpression {
(Salesrecord.Name! + " " + Salesrecord.Address!)
}
(If ! was the operator for unwrap on the fly). It seems a bit verbose to have to declare a new variable every time I want to use the result of bind just once.
Bind and Return methods are available on MyComputationExpression. Your original code is converted to this equivalent code:
MyComputationExpression.Bind(
Salesrecord.Address,
fun addr -> MyComputationExpression.Bind(
Salesrecord.Name,
fun name -> async.Return (name + " " + addr)))
This is quite ugly code, which is why computation expressions exist as a language feature. Being able to use them inline in the way that you want is currently not possible. It would be an additional language feature and it has been suggested before.
Your specific example may be easily called from an operator, in order to be inlined:
let inline (+?) a b =
MyComputationExpression(){
let! x = a
let! y = b
return x + y }
Some 3 +? None
salesrecord.Address +? Some " " +? salesrecord.Name
In more complicated cases, the need to explicity execute bind on the remainder of the computation may at least improve readability.

How would I get the index of a char in a string?

So, essentially i'm trying to create a function that solves for the value of x.
for example, x + 4 = 8
So I'm trying to make it so, it replaces x with "" and then it gets the symbol in front of it in this case, "+" and replaces it with ""
but In Order to do so, and not remove an imaginary symbol behind it, I need to make it check if the index is 1.
My Brain Hurts.
Here's what I have for the function, I deleted some of the code for getting the index, cause It didn't work.
mathMod.solveExpression = function(variable, expression)
if (string.find(expression, "=") == nil) then
-- void
else
-- continue with search but with variable
if (string.find(expression, variable) == nil) then
-- void
else
-- ooh time for some sneaky equations
local copy = expression
for i = 1, #expression do
local c = expression:sub(i,i)
if (expression == c) then
end
end
end
end
end
/ Link To My Code`https://pastebin.com/DnKPdw2q /
If your equations are all of the form var op a = b, try this code, which uses Lua pattern matching:
s=" x + 4 = 8 "
var,op,a,b = s:match("(%w+)%s*(%p)%s*(%d+)%s*=%s*(%d+)")
print(var,op,a,b)
The pattern captures the first word as the var, skips spaces, captures a punctuation char as the operation, skips spaces, captures operand a, skips the equal sign possibly surrounded by spaces, and finally captures operand b.

Converting a string to an array in Lua

Why does this syntax work:
if ({A=1,B=1,C=1})["A"] then print("hello") end
while this does not:
local m = {string.sub(string.gsub("A,B,C,", ",", "=1,"),1,-2)}
if (m)["A"] then print("hello") end
???
I think it's because a string is not an array, but how can I convert a string ("a,b,c") to an array ({a=1,b=1,c=1})?
This line
local m = {string.sub(string.gsub("A,B,C,", ",", "=1,"),1,-2)}
is equivalent to this
local v = string.sub(string.gsub("A,B,C,", ",", "=1,"),1,-2)
local m = {v}
which, I hope you agree, would clearly not have the behavior of assigning multiple values in the m table.
To "parse" simple a=1,b=1,c=1 type strings into a table the second example of string.gmatch from the manual is helpful:
The next example collects all pairs key=value from the given string into a table:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end

Ocaml: calling recursive function again

So I have a recursive function that takes in 2 ints, and a out_channel and basically prints line(a,a+1). It should do this until value of a is equal to b. I.e if a = 1, b = 5
line(1,2)
line(2,3)
...line(4,5)
> let rec print_line (out:out_channel)(a:int)(b:int) : unit =
if (a < b) then output_string out ("line("^string_of_int(a)^","^string_of_int(a+1)^")\n")
> ;;
I want to make it recursive where it keeps printing the line(a,a+1) until a is no longer less than b. How exactly do I call it again?
Any help would be appreciated.
So: first check whether a >= b in which case you are done and can return (). Otherwise print one line (the way you did) followed by recursive call to your function, with incremented a. So altogether:
let rec print_line (out:out_channel)(a:int)(b:int) : unit =
if a >= b then
()
else (
output_string out ("line("^string_of_int(a)^","^string_of_int(a+1)^")\n");
print_line out (a + 1) b
)

Resources