i have the following
List list1 = [];
List list2 = [];
list2 = list1 ;
list1.add(1);
print(list1); // outputs [1]
print(list2); // outputs [1] WHY?
i only change list1 .. why list2 is always be the same ..
sometimes in my app i need to make a list == another .. and this is great .. but once i make it they always be equals to each other even if i make a change to one of them
Assign list copy with List.of constructor method:
list2 = List.of(list1);
More explanation of pointers and how it works you can find at my answer here.
Related
I have a list like List = [{0,12},{0,12},{-1,0},{0,12},{0,4},{1,2}] and a string Str = "https://www.youtube.com/watch?v=WQfdwsPao9E", now I've to find all the substrings using start and end point from list.
I want substrings to be returned in a List like ["https://www","https://www",..]
I tried using this:
C=lists:map(fun({X,Y}) -> string:sub_string(Str,X,Y) end,List)
1> List = [{0,12},{0,12},{-1,0},{0,12},{0,4},{1,2}].
[{0,12},{0,12},{-1,0},{0,12},{0,4},{1,2}]
2> Str = "https://www.youtube.com/watch?v=WQfdwsPao9E".
"https://www.youtube.com/watch?v=WQfdwsPao9E"
3> Len = length(Str).
43
4> [string:sub_string(Str,max(1,X),min(Len,Y)) || {X,Y} <- List].
["https://www.","https://www.",[],"https://www.","http",
"ht"]
5>
you may have to adjust the indexes in the string to fit exactly to your need.
[edit] It looks like I didn't interpret correctly what is the meaning of the tuple. I think it is {Fist_Char_Index, Char_Number}, or {-1,0} if no match is found. So you should use:
[string:sub_string(Str,X+1,X+Y) || {X,Y} <- List, {X,Y} =/= {-1,0}].
HeirListFormatted = [{code, 1}, ...],
HeirCode = proplists:get_value(code, HeirListFormatted),
HeirList = [<<"1">>, <<"2">>, ...],
HeirListCodes = [case to_integer(X) of HeirCode -> []; _-> form_data:to_integer(X) end || X <- HeirList].
Here HeirListCodes is returning a list like this: [[],2, 3,[],...]. But I want the code in one line and HeirListCodes should return me a list like [2,3, ...].
Thank you inadvance!
Is it what you are looking for?
[Y || X <- HeirList , Y <- [binary_to_integer(X)],Y =/= HeirCode].
[Edit]
if HeirCode == undefined:
Without any change, the filter condition will be always true, and you will get the list of binaries transformed onto a list of integer.
If you add the filter condition HeirCode =/= undefined this filter will be always false, so the result will be an empty list.
So the solution really depend on the result you expect.
I am trying to iterate through an IDictionary (reasons explained later...) in F#, and round each value to a specified precision. Essentially this is what I'm trying to do:
List.iter (fun(x) -> a.Item(x) <- Math.Round(a.Item(x), input.precision)) (ICollectionToDoubleList a.Keys)
(where ICollectionToDoubleList takes the ICollection a.Keys and casts it to a double list).
However since you can't alter mutable variables inside closures, this doesn't compile.
My first attempt at a solution was this:
List.iter (fun(x) -> let p = Math.Round(a.Item(x), input.precision)
a.Item(x) := p
) (ICollectionToDoubleList a.Keys)
However I'm getting the error:
This expression was expected to have type
'a ref
but here has type
double
on a.Item(x)
I could convert the IDictionary into two lists (or a list of tuples), perform the rounding, and re-cast into an IDictionary, but this seems a bit messy and convoluted.
Any guidance greatly appreciated.
EDIT:
I forgot to mention a was defined as:
let mutable (a : IDictionary<double,double>) = ...
I think you want
a.Item(x) <- p
In F# you use <- to assign to mutable values, whilst := assign to ref values.
You could even use
a.[x] <- p
for a slightly simpler version.
Explaination of what mutable means (it behaves like the opposite of const in C)
let mutable m = [|1|]
let t = [|1|]
m.[0] <- 0
t.[0] <- 0 //neither of these change m or t - only elements so they are fine
m <- [|1;2;3;|] //fine as m is mutable
t <- [|1;2;3;|] //not allowed as t is not mutable
If you are used to const in C, the above are roughly equivalent to
int* m = {1};
const int* t = {1}
note, neither is equivalent to
const int* q const = {1}
which is I think what you thought not mutable meant.
Ok so I've discovered the answer...
I have defined a as:
let mutable (a : IDictionary<double,double>) = ...
If I change this to
let (a : IDictionary<double,double>) = ...
then this compiles. It seems a little counter-intuative to me that a non-mutable value can be mutated, but a mutatable variable cannot!!
I have a function which returns a sequence of records. In that function I start the list building with a blank dummy record (there is probably a better way to do it) because I need to accumulate records that are similar, so I "prime the pump" with a blank record. Here's my code:
let consolidate(somethings:seq<Something>) =
let mutable results = ResizeArray()
let mutable accumulatedSomething = {Foo = ""; Bar = ""; Count = 0;}
for s in somethings do
if s.Foo = accumulatedSomething.Foo && s.Bar = accumulatedSomething.Bar then
accumulatedSomething <- {Foo = s.Foo; Bar = s.Bar;
Count = s.Count + accumulatedSomething.Count}
else
results.Add(accumulatedSomething)
accumulatedSomething <- e
results |> Seq.cast |> Seq.skip 1
If you have a way to make this better I'm all ears (I'm still thinking procedurally) but I'm still interested in an answer to this specific question. Later on in my code, I try to print out the list:
somethings |> Seq.iter( fun s -> printfn "%A" s)
This works fine when there is stuff in the list. But if the list is empty and the only record that was in the list was the skipped blank starter record, then this line fails with an InvalidOperationException with the message The input sequence has an insufficient number of elements?
Why does this happen and how can I fix it?
The problem occurs when somethings is an empty list.
In this case, results is empty and calling Seq.skip 1 on the empty list fails with an error.
I think an elegant solution would be to change the last line to
match results.Length with
| 0 -> results |> Seq.cast
| _ -> results |> Seq.cast |> Seq.skip 1
Is it just me, or does F# not cater for cyclic lists?
I looked at the FSharpList<T> class via reflector, and noticed, that neither the 'structural equals' or the length methods check for cycles. I can only guess if 2 such primitive functions does not check, that most list functions would not do this either.
If cyclic lists are not supported, why is that?
Thanks
PS: Am I even looking at the right list class?
There are many different lists/collection types in F#.
F# list type. As Chris said, you cannot initialize a recursive value of this type, because the type is not lazy and not mutable (Immutability means that you have to create it at once and the fact that it's not lazy means that you can't use F# recursive values using let rec). As ssp said, you could use Reflection to hack it, but that's probably a case that we don't want to discuss.
Another type is seq (which is actually IEnumerable) or the LazyList type from PowerPack. These are lazy, so you can use let rec to create a cyclic value. However, (as far as I know) none of the functions working with them take cyclic lists into account - if you create a cyclic list, it simply means that you're creating an infinite list, so the result of (e.g.) map will be a potentially infinite list.
Here is an example for LazyList type:
#r "FSharp.PowerPack.dll"
// Valid use of value recursion
let rec ones = LazyList.consDelayed 1 (fun () -> ones)
Seq.take 5 l // Gives [1; 1; 1; 1; 1]
The question is what data types can you define yourself. Chris shows a mutable list and if you write operations that modify it, they will affect the entire list (if you interpret it as an infinite data structure).
You can also define a lazy (potentionally cyclic) data type and implement operations that handle cycles, so when you create a cyclic list and project it into another list, it will create cyclic list as a result (and not a potentionally infinite data structure).
The type declaration may look like this (I'm using object type, so that we can use reference equality when checking for cycles):
type CyclicListValue<'a> =
Nil | Cons of 'a * Lazy<CyclicList<'a>>
and CyclicList<'a>(value:CyclicListValue<'a>) =
member x.Value = value
The following map function handles cycles - if you give it a cyclic list, it will return a newly created list with the same cyclic structure:
let map f (cl:CyclicList<_>) =
// 'start' is the first element of the list (used for cycle checking)
// 'l' is the list we're processing
// 'lazyRes' is a function that returns the first cell of the resulting list
// (which is not available on the first call, but can be accessed
// later, because the list is constructed lazily)
let rec mapAux start (l:CyclicList<_>) lazyRes =
match l.Value with
| Nil -> new CyclicList<_>(Nil)
| Cons(v, rest) when rest.Value = start -> lazyRes()
| Cons(v, rest) ->
let value = Cons(f v, lazy mapAux start rest.Value lazyRes)
new CyclicList<_>(value)
let rec res = mapAux cl cl (fun () -> res)
res
The F# list type is essentially a linked list, where each node has a 'next'. This in theory would allow you to create cycles. However, F# lists are immutable. So you could never 'make' this cycle by mutation, you would have to do it at construction time. (Since you couldn't update the last node to loop around to the front.)
You could write this to do it, however the compiler specifically prevents it:
let rec x = 1 :: 2 :: 3 :: x;;
let rec x = 1 :: 2 :: 3 :: x;;
------------------------^^
stdin(1,25): error FS0260: Recursive values cannot appear directly as a construction of the type 'List`1' within a recursive binding. This feature has been removed from the F# language. Consider using a record instead.
If you do want to create a cycle, you could do the following:
> type CustomListNode = { Value : int; mutable Next : CustomListNode option };;
type CustomListNode =
{Value: int;
mutable Next: CustomListNode option;}
> let head = { Value = 1; Next = None };;
val head : CustomListNode = {Value = 1;
Next = null;}
> let head2 = { Value = 2; Next = Some(head) } ;;
val head2 : CustomListNode = {Value = 2;
Next = Some {Value = 1;
Next = null;};}
> head.Next <- Some(head2);;
val it : unit = ()
> head;;
val it : CustomListNode = {Value = 1;
Next = Some {Value = 2;
Next = Some ...;};}
The answer is same for all languages with tail-call optimization support and first-class functions (function types) support: it's so easy to emulate cyclic structures.
let rec x = seq { yield 1; yield! x};;
It's simplest way to emulate that structure by using laziness of seq.
Of course you can hack list representation as described here.
As was said before, your problem here is that the list type is immutable, and for a list to be cyclic you'd have to have it stick itself into its last element, so that doesn't work. You can use sequences, of course.
If you have an existing list and want to create an infinite sequence on top of it that cycles through the list's elements, here's how you could do it:
let round_robin lst =
let rec inner_rr l =
seq {
match l with
| [] ->
yield! inner_rr lst
| h::t ->
yield h
yield! inner_rr t
}
if lst.IsEmpty then Seq.empty else inner_rr []
let listcycler_sequence = round_robin [1;2;3;4;5;6]