how to assign variable dynamically? - mql4

int abc1 = 123;
int abc = 456;
int e = 1;
printf (abc+e);
supposedly it will output "123", but it fail with error "abc" is not declare.
How to fix the error?

Related

F# "This value is not a function and cannot be applied" when trying to add (+)

The m.Count + m.StepSize in the F# code, 4th line from the bottom, returns the error This value is not a function and cannot be applied.
I can't see why + isn't being interpreted as an infix function instead of m.Count.
Why is this line a problem?
type Model =
{ Count: int
StepSize: int }
type Msg =
| Increment
| Decrement
| SetStepSize of int
| Reset
let init =
{ Count = 0
StepSize = 1 }
let canReset = (<>) init
let update msg m =
match msg with
| Increment -> { m with Count = m.Count + m.StepSize }
| Decrement -> { m with Count = m.Count - m.StepSize }
| SetStepSize x -> { m with StepSize = x }
| Reset -> init

Casting user define type back to tuple

I am new to F#. I am working with a custom type which contains tuples.
type myType =
| obj1 of int * int
| obj2 of string * string
Now I have function which yields the sequence of this myType
type Response = XmlProvider<"""<Result><ns7:value>Item 1</ns7:value>`<ns7:status>1</ns7:status></Result>""", Global=true>`
let comparison (a:Response.Result) (b::Response.Result) = seq {
if a.Status <> b.Status then
yield Status(a.Value, a.Status, b.Status)
}
After that I get the array of myType
let a = """<Result><ns7:value>Item 1</ns7:value>`<ns7:status>1</ns7:status></Result>"""
let b = """<Result><ns7:value>Item 1</ns7:value>`<ns7:status>1</ns7:status></Result>"""
let compareResults = comparison a b |> Seq.toArray
My question is when a traverse through compareResults, how can I get back tuple obj1 and obj2. Currently all I am getting is the object of myType. Is there a way to cast that back into a tuple?
Update
module Script.File1
open System
open FSharp.Data
open HttpClient
type myType =
| Obj1 of string * int * int
| Obj2 of string * string
type Response = XmlProvider<"""<Result><value>Item 1</value><status>1</status></Result>""", Global=true>
let comparison (a:Response.Result) (b:Response.Result) = seq {
if a.Status <> b.Status then
yield Obj1(a.Value, a.Status, b.Status)
}
let a = Response.Parse("""<Result><value>Item 1</value><status>1</status></Result>""")
let b = Response.Parse("""<Result><value>Item 1</value><status>1</status></Result>""")
let compareResults = comparison a b |> Seq.toArray
let run () =
for c in compareResults do
printfn " - %O" c
Assuming you have something like this (to start with a simplified compilable example):
type MyType =
| Obj1 of int * int
| Obj2 of string * string
let demo = seq {
for i in 0 .. 9 do
yield Obj1(i, i) }
Now, demo is a sequence of MyType values that all happen to be Obj1. You can pattern match on the values, but you will need to cover both of the cases, because the compiler does not know that all values in the sequence all Obj1:
for d in demo do
match d with
| Obj1(i1, i2) -> printfn "%d %d" i1 i2
| _ -> failwith "Should not happen"
If you want to avoid this, you could just yield a pair of integers so that the type of demo is seq<int * int>. Then you can iterate over that easily or you can wrap it into Obj1 when needed.
Alternatively, you could change your type definition so that the value is a tuple (wrapped with extra parentheses) rather than just two elements:
type MyType =
| Obj1 of (int * int)
| Obj2 of (string * string)
Now you can more easily pass the int * int value around. For example:
let demo = seq {
for i in 0 .. 9 do
yield i, i }
// Turn sequence of tuples into `MyType`
let objs = Seq.map Obj1 demo
// Iterate over a sequence of tuples
for i1, i2 in demo do
printfn "%d %d" i1 i2

How can I link a label to a mutable variable in F#?

I want to create a label in F# which uses a mutable variable to return a value. Unfortunately F# sets this label to a constant value. If the value of the mutable changes, the value of the label remains. Isn't it a bit inconsistent? Is there a way to get the label ("a") being dependent of the mutable ("x")?
let mutable x = 0;
let a = x + 2; // I want not to set a to a constant value
let b two = x + two;
x <- 1;
let c = b 2;
let isConsistent = a = c;
val mutable x : int = 1
val a : int = 2
val b : two:int -> int
val c : int = 3
val isConsistent : bool = false
From your own comment you want a to be a function returning x + 2
Direct translation of that is :
let mutable x = 0
let a () = x + 2
let b two = x + two
x <- 1
let c = b 2
let isConsistent = a () = c // don't forget to call the function 'a'
(*
val mutable x : int = 1
val a : unit -> int
val b : two:int -> int
val c : int = 3
val isConsistent : bool = true
*)

Rewrite a function in a more functional way

I wrote this function which computes the palindrome of a number :
let palindrome n =
let mutable current = n
let mutable result = 0
while(current > 0) do
result <- result * 10 + current % 10
current <- current / 10
result
How can I rewrite it in a more functional way ?
It's not quite clear what you want to do. The palindrome function as given simply reverses the digits of an integer:
> palindrome 1;;
val it : int = 1
> palindrome 12;;
val it : int = 21
> palindrome 123;;
val it : int = 321
> palindrome 9852;;
val it : int = 2589
Those aren't palindromic numbers, but let's split the problem into smaller building blocks.
You can easily split an integer into a list of digits. In fact, splitting into a reverse list of digits is the easiest way I could think of:
let rec revdigits i =
let tens = i / 10
if tens = 0
then [i]
else
let ones = i % 10
ones :: revdigits tens
This is a function of the type int -> int list.
Examples:
> revdigits 1;;
val it : int list = [1]
> revdigits 12;;
val it : int list = [2; 1]
> revdigits 123;;
val it : int list = [3; 2; 1]
> revdigits 9852;;
val it : int list = [2; 5; 8; 9]
It's also easy to concatenate a list of digits into a number:
let rec concat digits =
match digits with
| [] -> 0
| h :: t -> h * int (10. ** float t.Length) + concat t
This function has the type int list -> int.
Examples:
> concat [1];;
val it : int = 1
> concat [1; 2];;
val it : int = 12
> concat [1; 2; 3];;
val it : int = 123
> concat [2; 5; 8; 9];;
val it : int = 2589
With these building blocks, you can easily compose a function that does the same as the palindrome function:
let reverse = revdigits >> concat
This function has the type int -> int.
Examples:
> reverse 1;;
val it : int = 1
> reverse 12;;
val it : int = 21
> reverse 123;;
val it : int = 321
> reverse 2589;;
val it : int = 9852
Bonus: if you don't want to reverse the digits, you can do it like this instead, but I don't think this version is tail recursive:
let rec digits i =
let tens = i / 10
if tens = 0
then [i]
else
let ones = i % 10
digits tens # [ones]
This function has the type int -> int list.
Examples:
> digits 1;;
val it : int list = [1]
> digits 12;;
val it : int list = [1; 2]
> digits 123;;
val it : int list = [1; 2; 3]
> digits 9852;;
val it : int list = [9; 8; 5; 2]
You can do it with a tail-recursive function. Match the value of result : if his value = 0 then return the result else do the computations on current and result.
let palindrome n =
let rec rec_palindrome current result = match current with
| 0 -> result
| _ -> rec_palindrome (result * 10 + current % 10) (current / 10)
rec_palindrome n 0
Plus, in my version, this is no mutable values.

F# quotation evaluation issue

I'm getting an issue with the F# powerpack quotation evaluation.
open Microsoft.FSharp.Linq.QuotationEvaluation
let print x = System.Console.WriteLine(sprintf "%A" x)
type record = { x:int; y:int }
let val1 = { x = 1; y = 1; }
let val2 = { x = 1; y = 1; }
let result = val1 = val2
print result
let quote = <# let value1 = { x = 1; y = 1; }
let value2 = { x = 1; y = 1; }
let result2 = value1 = value2
result2 #>
print (quote.EvalUntyped())
The first result is true as you would expect. The second is false. Is this a bug, or am I missing something?
This looks like a bug to me. Someone from the F# team will probably give a clear answer on this :-). In the meantime, here is a simple workaround that you can use - The problem seems to be with the compilation of the = operator. You can define your own operator (or a function) and call this operator from the quoted code:
let (><) a b = a = b
let quote =
<# let value1 = { x = 1; y = 1; }
let value2 = { x = 1; y = 1; }
let result2 = value1 >< value2
result2 #>
print (quote.EvalUntyped())
Instead of generating a wrong call to the standard = operator, this will generate code that calls your custom operator (which then runs the comparison as a standard, correctly compiled F# code), so this gives the expected result.

Resources