How To Use The <- Operator - f#

let mutable steve = 1348;
let steve <- 202;
printfn "%d" steve;
System.Console.ReadKey();
I cannot simply get the num. 202 to print out in the Console. What am I dpoing wrong anyway?

You don't need the 2nd "let", nor the semicolons.
let mutable steve = 1348
steve <- 202
printfn "%d" steve
System.Console.ReadKey() |> ignore

Related

Second to last item in a list in F#

This is what my initial thought was and there were no issues until it was called; What is wrong with this exactly?
let SecLastItem myList=
List.rev myList
|>printfn myList.[1]
How do I rectify the problem here? What is the best way to find the 2nd to last item of a list?
printfn expects a format first printfn "%A" arg
But there is more, functional programming favors immutability so List.rev returns a new list without modifying mylist
So printing the second item in myList won't give the second to last just the second from start (if it exists otherwise it'll crash)
That said you should separate function doing something and logging/printing that' better for reuse and composability.
// trySecLastItem : 'a list -> 'a option
let trySecLastItem = List.rev >> List.tryItem 2
// usage
printfn "%d" (trySecLastItem someList) // ex Some 42 or None
Now as trySecLastItem returns an option you have to take care of that (using defaultArg for example)
// maybeSecLast : int option
let maybeSecLast = trySecLastItem someList
printfn "%d" (defaultArg maybeSecLast 42)
What is the best way to find the 2nd to last item of a list?
If you do not want to reverse the list, you can use pattern matching and return an option if the list is not long enough for a 'second to last item'. Something like this.
let rec secondToLast ls =
match ls with
| [] -> None
| h :: ht :: [] -> Some(h)
| h :: t -> secondToLast t
test with
printfn "%A" (secondToLast [1; 2; 3; 4])
You need to have a formatter with printfn
let SecLastItem myList=
let revList = List.rev myList
printfn "%A" revList.[1]

Range Operator for Base62 Encoding

For base 62 encoding, I need all 62 alphanumeric characters. The F# range operator offers a nice shorthand for this.
let alphaNumericCharacters =
seq {
yield! [|'a'..'z'|]
yield! [|'A'..'Z'|]
yield! [|'0'..'9'|]
} |> Array.ofSeq
This is nice and concise, but I'm greedy. Is there a way of doing this in one line?
let alphaNumericCharacters = Array.concat [| [|'0'..'9'|]; [|'A'..'Z'|]; [|'a'..'z'|] |]
let alphaNumericCharacters = ['a'..'z'] # ['A'..'Z'] # ['0'..'9'] |> List.toArray
If your feeling funny:
let alphaNumericCharacters = [|Char.MinValue..Char.MaxValue|] |> Array.filter Char.IsLetterOrDigit

printfn in pipeline

So I have a function SolveEquasion that returns a pair float*float[]. What is the best way to print the number and the array and continue working with the array? I made the following code but it seems there is a better way
...
|> SolveEquasion
|> (fun (det, solution) -> printfn "Determinant = %f\nSolution = %A" det (Array.toList solution), solution )
|> snd
I don't think your solution can improved if you want to do this in a pipeline. Another approach is to use a let binding, along with splitting up the pipelined operations, to avoid having a function that acts like the love child of map and iter.
let (det, solution) = SolveEquasion
printfn "Determinant = %f\nSolution = %A" det (Array.toList solution)
//do something else with solution
I think the original solution is fine, and we can improve its clarity by giving your anonymous function the name I've seen it given in some other libraries based around pipelining higher-order functions: tap.
let tap f x =
f x
x
(1.0, [| 2.0; 3.0 |])
|> tap (fun (s, a) -> printfn "%A %A" s a)
|> snd
Well, for one thing you can skip the use of snd by returning a single value rather than a tuple from the previous function:
...
|> SolveEquasion
|> (fun (det, solution) ->
printfn "Determinant = %f\nSolution = %A" det (Array.toList solution)
solution )
I'd probably use Daniel's approach and just assign the value you want to print to a symbol using let. Alternatively, you could define a variant of printf that takes some arguments and returns one of them. I'm not sure if there is a general scheme how this should be done - for your example it would take a two-element tuple:
let mprintf fmt (a, b) =
Printf.kprintf (fun s -> printf "%s" s; (a, b)) fmt a b
Then you can write:
...
|> SolveEquasion
|> mprintfn "Determinant = %f\nSolution = %A"
|> snd |> // ... more stuff with solution

F# How to Count Number of elements in a list that match some criteria?

I am prototyping how I am going to handle Double.NaN values in an F# array, and the first step, trying to simply count how many there are, has me stumped. The value "howMany" comes back as zero in my code, but I know there are 2, because I set 2 value to be Double.NaN. Can anyone point out what I am missing? Thanks!
let rnd = new System.Random()
let fakeAlphas = Array.init 10 (fun _ -> rnd.NextDouble());;
fakeAlphas.[0] <- Double.NaN;
fakeAlphas.[1] <- Double.NaN;
let countNA arr = arr |> Array.filter (fun x -> x = Double.NaN) |> Array.length;;
let howMany = countNA fakeAlphas;;
To answer the general question in the title:
let HowManySatisfy pred = Seq.filter pred >> Seq.length
for example
let nums = [1;2;3;4;5]
let countEvens = nums |> HowManySatisfy (fun n -> n%2=0)
printfn "%d" countEvens
Double.NaN = n is false for all n. See the MSDN page for Double.NaN.
Instead use Double.IsNaN. See the MSDN page for more information.
I think you need to use the Double.IsNan method. So your filter function would be:
(fun x -> Double.IsNan x)
I believe the issue is that NaN never equals anything -- even another NaN!

How do I print an entire list in F#?

When I use Console.WriteLine to print a list, it defaults to only showing the first three elements. How do I get it to print the entire contents of the list?
You can use the %A format specifier along with printf to get a 'beautified' list printout, but like Console.WriteLine (which calls .ToString()) on the object, it will not necessarily show all the elements. To get them all, iterate over the whole list. The code below shows a few different alternatives.
let smallList = [1; 2; 3; 4]
printfn "%A" smallList // often useful
let bigList = [1..200]
printfn "%A" bigList // pretty, but not all
printfn "Another way"
for x in bigList do
printf "%d " x
printfn ""
printfn "Yet another way"
bigList |> List.iter (printf "%d ")
printfn ""
You can iterate over the it, using the List.iter function, and print each element:
let list = [1;2;3;4]
list |> List.iter (fun x -> printf "%d " x)
More info:
Lists in F# (MSDN)
Here's simple alternative that uses String.Join:
open System
let xs = [1; 2; 3; 4]
let s = "[" + String.Join("; ", xs) + "]"
printfn "%A" s

Resources