i'm writing a small console application in F#.
[<EntryPoint>]
let main argv =
high_lvl_funcs.print_opt
let opt = Console.ReadLine()
match opt with
| "0" -> printfn "%A" (high_lvl_funcs.calculate_NDL)
| "1" -> printfn ("not implemented yet")
| _ -> printfn "%A is not an option" opt
from module high_lvl_funcs
let print_opt =
let options = [|"NDL"; "Deco"|]
printfn "Enter the number of the option you want"
Array.iteri (fun i x -> printfn "%A: %A" i x) options
let calculate_NDL =
printfn ("enter Depth in m")
let depth = lfuncs.m_to_absolute(float (Console.ReadLine()))
printfn ("enter amount of N2 in gas (assuming o2 is the rest)")
let fn2 = float (Console.ReadLine())
let table = lfuncs.read_table
let tissue = lfuncs.create_initialise_Tissues ATM WATERVAPOUR
lfuncs.calc_NDL depth fn2 table lfuncs.loading_constantpressure tissue 0.0
lfuncs.calc_NDL returns a float
this produces this
Enter the number of the option you want
0: "NDL"
1: "Deco"
enter Depth in m
which means it prints what it's suppose to then jumps straight to high_lvl_funcs.calculate_NDL
I wanted it to produce
Enter the number of the option you want
0: "NDL"
1: "Deco"
then let's assume 0 is entered, and then calculate high_lvl_funcs.calculate_NDL
after some thinking and searching i assume this is because F# wants to assign all values before it starts the rest. Then i thought that i need to declaring a variable without assigning it. but people seem to agree that this is bad in functional programming. From another question: Declaring a variable without assigning
so my question is, is it possible to rewrite the code such that i get the flow i want and avoid declaring variables without assigning them?
You can fix this by making calculate_NDL a function of no arguments, instead of a closure that evaluates to a float:
let calculate_NDL () =
Then call it as a function in your match like this:
match opt with
| "0" -> printfn "%A" (high_lvl_funcs.calculate_NDL())
However I'd suggest refactoring this code so that calculate_NDL takes any necessary inputs as arguments rather than reading them from the console i.e. read the inputs from the console separately and pass them to calculate_NDL.
let calculate_NDL depth fn2 =
let absDepth = lfuncs.m_to_absolute(depth)
let table = lfuncs.read_table
let tissue = lfuncs.create_initialise_Tissues ATM WATERVAPOUR
lfuncs.calc_NDL absDepth fn2 table lfuncs.loading_constantpressure tissue 0.0
It's generally a good idea to write as much code as possible as pure functions that don't rely on I/O (like reading from stdin).
Related
I want to create a function that check if the passed value is greater than zero.
The passed value can be an int or a decimal (ideally a "numeric value").
In the immediate I just started with this:
type number =
| I of int
| D of decimal
type Checker () =
member this.Validate value =
match value with
| I x when x > 0 -> "ok"
| D x when x > 0m -> "ok"
| _ -> "error"
let a = 1f
let b = 1m
//let a_IsValid = Checker().Validate(a) // does not compile, expect number (not int)
//let b_IsValid = Checker().Validate(b) // does not compile, expect number (not decimal)
Found not immediate to pass a "number" so tried something different...
I found this article (http://tomasp.net/blog/fsharp-generic-numeric.aspx/) and I thought
"static member constraint" is the perfect solution for me.
A basic example works as expected:
let inline divideByTwo value =
LanguagePrimitives.DivideByInt value 2
divideByTwo 1f |> ignore
divideByTwo 1m |> ignore
but a different scenario found me very surprised:
type Calculator () =
let divideByTwo value =
LanguagePrimitives.DivideByInt value 2
member this.DivideByTwo value =
LanguagePrimitives.DivideByInt value 2
member this.ValidateGeneric value =
match LanguagePrimitives.GenericGreaterThan value 0m with
| true -> "ok"
| _ -> "error"
//let half = Calculator().DivideByTwo(1) // DivideByInt does not support int !!
// cannot use both the following, the first one will "force" the type, and the other will not work
let a_half = Calculator().DivideByTwo(1f) // ok if used before the "decimal" version
let b_half = Calculator().DivideByTwo(1m) // ok only if comment the previous one
It seems not to work when I want to use more than one type for the passing value.
More than that, the function I need (GenericGreaterThan) seems to have another "limitation", explained below.
The example in the article use DivideByInt and, as the name said, it divide the passed value by an int, a well defined type.
LanguagePrimitives.GenericGreaterThan needs 2 parameters, a passed value and a fixed one to compare to. The signature of the function as only one generic type for both, so if you pass a type 'T it expect the second one to be 'T too.
I just wants to compare with zero without passing it, but using "0" forced my value
to be an int and using "0m" force the value to be a decimal.
There is a simple way to have a function that check if a "numeric" value is greater than "zero" ?
Should I use obj and box it .... or use cast ... or stop trying and just use a different function for every type I need ?
[UPDATE]
I tried to use the LanguagePrimitives.GenericZero as suggested but still not able to have a working solution for my particular scenario.
I created a new issue here: F# - Compare LanguagePrimitives.GenericZero with a value passed on the class contructor .
Comparing against zero generically is actually quite simple. The following function should work for any numeric type:
let inline isPositive x =
x > LanguagePrimitives.GenericZero
isPositive 1.0 |> printfn "%A" // true
isPositive 1m |> printfn "%A" // true
Dividing by two generically is also pretty easy. You just have to define your own generic two, since it's not a built-in primitive:
let inline divideByTwo x =
let two =
LanguagePrimitives.GenericOne
+ LanguagePrimitives.GenericOne
x / two
divideByTwo 5.0 |> printfn "%A" // 2.5
divideByTwo 4m |> printfn "%A" // 2
there lots of things here.
your first example didn't work because you needed to wrap your number inside the type number (I assume you realise this? but didnt want it to work like that?)
type Checker () =
member this.Validate value =
match value with
| I x when x > 0 -> "ok"
| D x when x > 0m -> "ok"
| _ -> "error"
let a = I 1
let b = D 1m
let a_IsValid = Checker().Validate(a)
let b_IsValid = Checker().Validate(b)
your second example is that in doesnt support divide by int?
yes what is the value of 1/2? its not an int, so thats correct by design.
the third question seems to be that this code doesnt compile and run?
type Calculator () =
member inline _.DivideByTwo value =
LanguagePrimitives.DivideByInt value 2
let b_half = Calculator().DivideByTwo(1m) // ok for me
let a_half = Calculator().DivideByTwo(1f) // ok for me
but this works for me.
The fourth question appears to be the need to use static constraints to test if something is > 0?
but 0 (as in mathematics) is a different thing in different number systems, its generic too so you need LanguagePrimitives.GenericZero. putting that all together we get
type Calculator () =
member inline _.DivideByTwo value =
LanguagePrimitives.DivideByInt value 2
member inline _.ValidateGeneric value =
match LanguagePrimitives.GenericGreaterThan
value
LanguagePrimitives.GenericZero with
| true -> "ok"
| _ -> "error"
let b_half = Calculator().DivideByTwo(1m)
let a_half = Calculator().DivideByTwo(1f)
let y = Calculator().ValidateGeneric(1m)
let z = Calculator().ValidateGeneric(1f)
as for the divide by 1/2 question, you may need to think what you want it to do? really the input type is defined by what output type you want? decimal? float? etc
I want to make a small simulation, but I can't figure out how to make the board for the simulation.
I want to make a simulation where there are two kind of animals predators and prey.
The simulation should be given an input n, which determines the size of the board. So that it is n x n squares big.
I have tried to use a 2D array, but I don't completely understand it and when I try to print my board it doesn't show up.
I have an .fs file with this code
module preditorprey
type board(n:int) =
let _rows = n
let _columns = n
let _board = Array2D.create _rows _columns (None)
I then have an .fsx file with this
open preditorprey
let boards = preditorprey.board(8)
printfn "%A" boards
However when I run the code it just returns
preditorprey+board
Why does it do this and how do I make it print out a board with n*n squares???
Why does it do this
You created a class board and defined some private fields. You are surprised that printfn "%A" does not return the data inside the Board type. Since the fields inside the Board type are private, no function can access them, so this would not be possible.
printfn "%A" has special code to print a lot of F# structures in a reasonably intelligent way. For classes it will use the ToString() method which defaults to printing out the class name.
how do I make it print out a board with n*n squares???
For something quick and dirty (i.e. without specifying what you mean by printing out a board but just relying on a moderate approach and a lot of defaults), you could do one of the following. Note the conventional naming: Pascal case for types, caml case for fields. Also note that you are missing a type annotation on None.
type NeedsToBeSpecified = class end
let boardA(n:int) = Array2D.create n n (None: NeedsToBeSpecified option)
let a = boardA(8)
printfn "%A" a
type BoardB(n:int) =
let board = Array2D.create n n (None: NeedsToBeSpecified option)
member t.Board = board
let b = BoardB(8)
printfn "%A" b.Board
type BoardC(n:int) =
let board = Array2D.create n n (None: NeedsToBeSpecified option)
override _.ToString() = sprintf "%A" board
let z = BoardC(8)
printfn "%A" z
I'm trying to wrap my head around mon-, err, workflows in F# and while I think that I have a pretty solid understanding of the basic "Maybe" workflow, trying to implement a state workflow to generate random numbers has really got me stumped.
My non-completed attempt can be seen here:
let randomInt state =
let random = System.Random(state)
// Generate random number and a new state as well
random.Next(0,1000), random.Next()
type RandomWF (initState) =
member this.Bind(rnd,rest) =
let value, newState = rnd initState
// How to feed "newState" into "rest"??
value |> rest
member this.Return a = a // Should I maybe feed "initState" into the computation here?
RandomWF(0) {
let! a = randomInt
let! b = randomInt
let! c = randomInt
return [a; b; c]
} |> printfn "%A"
Edit: Actually got it to work! Not exactly sure how it works though, so if anyone wants to lay it out in a good answer, it's still up for grabs. Here's my working code:
type RandomWF (initState) =
member this.Bind(rnd,rest) =
fun state ->
let value, nextState = rnd state
rest value nextState
member this.Return a = fun _ -> a
member this.Run x = x initState
There are two things that make it harder to see what your workflow is doing:
You're using a function type for the type of your monad,
Your workflow not only builds up the computation, it also runs it.
I think it's clearer to follow once you see how it would look without those two impediments. Here's the workflow defined using a DU wrapper type:
type Random<'a> =
Comp of (int -> 'a * int)
let run init (Comp f) = f init
type Random<'a> with
member this.Run(state) = fst <| run state this
type RandomBuilder() =
member this.Bind(Comp m, f: 'a -> Random<_>) =
Comp <| fun state ->
let value, nextState = m state
let comp = f value
run nextState comp
member this.Return(a) = Comp (fun s -> a, s)
let random = RandomBuilder()
And here is how you use it:
let randomInt =
Comp <| fun state ->
let rnd = System.Random(state)
rnd.Next(0,1000), rnd.Next()
let rand =
random {
let! a = randomInt
let! b = randomInt
let! c = randomInt
return [a; b; c ]
}
rand.Run(0)
|> printfn "%A"
In this version you separately build up the computation (and store it inside the Random type), and then you run it passing in the initial state. Look at how types on the builder methods are inferred and compare them to what MSDN documentation describes.
Edit: Constructing a builder object once and using the binding as an alias of sorts is mostly convention, but it's well justified in that it makes sense for the builders to be stateless. I can see why having parameterized builders seems like a useful feature, but I can't honestly imagine a convincing use case for it.
The key selling point of monads is the separation of definition and execution of a computation.
In your case - what you want to be able to do is to take a representation of your computation and be able to run it with some state - perhaps 0, perhaps 42. You don't need to know the initial state to define a computation that will use it. By passing in the state to the builder, you end up blurring the line between definition and execution, and this simply makes the workflow less useful.
Compare that with async workflow - when you write an async block, you don't make the code run asynchronously. You only create an Async<'a> object representing a computation that will produce an object of 'a when you run it - but how you do it, is up to you. The builder doesn't need to know.
I am trying to use the Math.NET numerics implementation of the FFT algorithm, but I must be doing something wrong because the output is always unit
The following is the the setup:
open MathNet.Numerics
open MathNet.Numerics.Statistics
open MathNet.Numerics.IntegralTransforms
let rnd = new Random()
let rnddata = Array.init 100 (fun u -> rnd.NextDouble())
let x = rnddata |> Array.Parallel.map (fun d -> MathNet.Numerics.complex.Create(d, 0.0) )
then when I run this:
let tt = MathNet.Numerics.IntegralTransforms.Fourier.BluesteinForward(x, FourierOptions.Default)
I receive an empty output below?
val tt : unit = ()
Any ideas why?
I think the Fourier.BluesteinForward method stores the results in the input array (by overwriting whatever was there originally).
If you do not need the input after running the transform, you can just use x and read the results (this saves some memory copying, which is why Math.NET does that by default). Otherwise, you can clone the array and wrap it in a more functional style code like this:
let bluesteinForward input =
let output = Array.copy input
MathNet.Numerics.IntegralTransforms.Fourier.BluesteinForward
(output, FourierOptions.Default)
output
There is any way to do it like C/C#?
For example (C# style)
for (int i = 0; i < 100; i++)
{
if (i == 66)
break;
}
The short answer is no. You would generally use some higher-order function to express the same functionality. There is a number of functions that let you do this, corresponding to different patterns (so if you describe what exactly you need, someone might give you a better answer).
For example, tryFind function returns the first value from a sequence for which a given predicate returns true, which lets you write something like this:
seq { 0 .. 100 } |> Seq.tryFind (fun i ->
printfn "%d" i
i=66)
In practice, this is the best way to go if you are expressing some high-level logic and there is a corresponding function. If you really need to express something like break, you can use a recursive function:
let rec loop n =
if n < 66 then
printfn "%d" n
loop (n + 1)
loop 0
A more exotic option (that is not as efficient, but may be nice for DSLs) is that you can define a computation expression that lets you write break and continue. Here is an example, but as I said, this is not as efficient.
This is really ugly, but in my case it worked.
let mutable Break = false
while not Break do
//doStuff
if breakCondition then
Break <- true
done
This is useful for do-while loops, because it guarantees that the loop is executed at least once.
I hope there's a more elegant solution. I don't like the recursive one, because I'm afraid of stack overflows. :-(
You have to change it to a while loop.
let (i, ans) = (ref 0, ref -1)
while(!i < 100 and !ans < 0) do
if !i = 66 then
ans := !i
ans
(This breaks when i gets to 66--but yes the syntax is quite different, another variable is introduced, etc.)
seq {
for i = 0 to 99 do
if i = 66 then yield ()
}
|> Seq.tryItem 0
|> ignore
Try this:
exception BreakException
try
for i = 0 to 99 do
if i = 66 then
raise BreakException
with BreakException -> ()
I know that some folks don't like to use exceptions. But it has merits.
You don't have to think about complicated recursive function. Of
cause you can do that, but sometimes it is unnecessarily bothersome
and using exception is simpler.
This method allows you to break at halfway of the loop body. (Break "flag" method is simple too but it only allows to break at the end of the loop body.)
You can easily escape from nested loop.
For these kind of problems you could use a recursive function.
let rec IfEqualsNumber start finish num =
if start = finish then false
elif
start = num then true
else
let start2 = start + 1
IfEqualsNumber start2 finish num
Recently I tried to solve a similar situation:
A list of, say, 10 pieces of data. Each of them must be queried against a Restful server, then get a result for each.
let lst = [4;6;1;8]
The problem:
If there is a failed API call (e.g. network issue), there is no point making further calls as we need all the 10 results available. The entire process should stop ASAP when an API call fails.
The naive approach: use List.map()
lst |> List.map (fun x ->
try
use sqlComd = ...
sqlComd.Parameters.Add("#Id", SqlDbType.BigInt).Value <- x
sqlComd.ExecuteScala() |> Some
with
| :? System.Data.SqlClient.SqlException as ex -> None
)
But as said, it's not optimal. When a failed API occurs, the remaining items keep being processed. They do something that is ignored at the end anyway.
The hacky approach: use List.tryFindIndex()
Unlike map(), we must store the results somewhere in the lamda function. A reasonable choice is to use mutable list. So when tryFindIndex() returns None, we know that everything was ok and can start making use of the mutable list.
val myList: List<string>
let res = lst |> List.tryFindIndex (fun x ->
try
use sqlComd = ...
sqlComd.Parameters.Add("#Id", SqlDbType.BigInt).Value <- x
myList.Add(sqlComd.ExecuteScala())
false
with
|:? System.Data.SqlClient.SqlException as ex -> true
)
match res with
| Some _ -> printfn "Something went wrong"
| None -> printfn "Here is the 10 results..."
The idiomatic approach: use recursion
Not very idiomatic as it uses Exception to stop the operation.
exception MyException of string
let makeCall lstLocal =
match lstLocal with
| [] -> []
| head::tail ->
try
use sqlComd = ...
sqlComd.Parameters.Add("#Id", SqlDbType.BigInt).Value <- x
let temp = sqlComd.ExecuteScala()
temp :: makeCall (tail)
with
|:? System.Data.SqlClient.SqlException as ex -> raise MyException ex.Message
try
let res = makeCall lst
printfn "Here is the 10 results..."
with
| :? MyException -> printfn "Something went wrong"
The old-fashion imperative approach: while... do
This still involves mutable list.