How to implement a simple Id-Generator? [closed] - f#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I have:
type Id = Id of int
let mutable IdInt = 0
let idGenerator =
fun _ ->
IdInt <- IdInt + 1
IdInt |> Id
which is then called like e.g:
printfn "%A" (idGenerator())
What's best practice to generate simple, incremental Ids in F#?

Your implementation is pretty much what I would do. There are two things that I'd change:
Define the argument of the inline function as unit so that there is no confusion about its type
Keep the mutable IdInt variable local to the idGenerator so that it's hidden (and you can also use more idiomatic camelCase naming for it)
So, my slightly modified version would be:
let idGenerator =
let mutable idInt = 0
fun () ->
idInt <- idInt + 1
idInt |> Id
In some cases, it is also useful to make this a function that creates new generators (in case you want to have more local generators rather than one global):
let makeIdGenerator () =
let mutable idInt = 0
fun () ->
idInt <- idInt + 1
idInt |> Id
let idGen1 = makeIdGenerator ()
let idGen2 = makeIdGenerator ()
The two generators will independently generate IDs starting from 1. They are independent, because the idInt variable is now local, so it's not shared by the two generators.

Related

Using BlockingCollection<'a>.TryTake in F#

This is related to an old question:
How to consume BlockingCollection<'a>.TryTake in F#
where the answer is more or less that we can't use it because the byref part should be at the end of the parameter list to make it possible.
8 years have passed since this question: are there any similar blocking queues with a timeout that I can use in F#?
You can use TryTake from F# without issues, but you can't use it as tuple returns. For exmaple, in FSI, this code:
open System.Collections.Concurrent
let bc = new BlockingCollection<int>()
let mutable item = 0
bc.Add 42
let success = bc.TryTake(&item, 100)
Will work fine, and result in the following output:
val bc : BlockingCollection<int>
val mutable item : int = 42
val success : bool = true

F# hidden mutation

Anyone have a decent example, preferably practical/useful, they could post demonstrating the concept?
I came across this term somewhere that I’m unable to find, probably it has to do something with a function returning a function while enclosing on some mutable variable. So there’s no visible mutation.
Probably Haskell community has originated the idea where mutation happens in another area not visible to the scope. I maybe vague here so seeking help to understand more.
It's a good idea to hide mutation, so the consumers of the API won't inadvartently change something unexpectedly. This just means that you have to encapsulate your mutable data/state. This can be done via objects (yes, objects), but what you are referring to in your question can be done with a closure, the canonical example is a counter:
let countUp =
let mutable count = 0
(fun () -> count <- count + 1
count)
countUp() // 1
countUp() // 2
countUp() // 3
You cannot access the mutable count variable directly.
Another example would be using mutable state within a function so that you cannot observe it, and the function is, for all intents and purposes, referentially transparent. Take for example the following function that reverses a string not character-wise, but rather by taking individual text elements (which, depending on language, can be more than one character):
let reverseStringU s =
if Core.string.IsNullOrEmpty s then s else
let rec iter acc (ee : System.Globalization.TextElementEnumerator) =
if not <| ee.MoveNext () then acc else
let e = ee.GetTextElement ()
iter (e :: acc) ee
let inline append x s = (^s : (member Append : ^x -> ^s) (s, x))
let sb = System.Text.StringBuilder s.Length
System.Globalization.StringInfo.GetTextElementEnumerator s
|> iter []
|> List.fold (fun a e -> append e a) sb
|> string
It uses a StringBuilder internally but you cannot observe this externally.

Stackless trampoline Monad/Computation Expression

I am working on a functional programming language of my own design and I stumbled on a problem that is beyond my skills to solve. I would like to know if anyone has any advice on how to solve it or a reason for why it is impossible.
The code below is an overview of a solution that is not the ideal but a compromise.
This problem is at the heart of the runtime system I am currently using. Instead of relying on the .Net stack I am using a monad to perform operations on a trampoline. This should help with step through debugging and allow for users to not have to worry about stack space. Here is a simplified version of the monad I am currently using.
type 't StackFree =
|Return of 't //Return a value
|StackPush of ('t->'t StackFree)*'t StackFree //Pushes a return handler onto the "Stack"
|Continuation of (unit->'t StackFree) //Perform a simple opperation
type StackFreeMonad() =
member this.Delay(fn) =
Continuation(fn)
member this.Bind(expr,fn) =
StackPush(fn,expr)
member this.Return(value) =
Return(value)
member this.ReturnFrom(x) =x
let stackfree = StackFreeMonad()
This was not the original design but it was the best I could get to work with F# computation expressions in an ideal world the above computation expression would work on this type.
type 't Running =
|Result of 't
|Step of (unit->'t Running)
So in order to convert a StackFree into a Running type I have to use this conversion function
//this method loops through the StackFree structure finding the next computation and managing a pseudo stack with a list.
let prepareStackFree<'t> :'t StackFree->'t Running =
let rec inner stack stackFree =
Step(fun ()->
match stackFree with
//takes the return values and passes it to the next function on the "Stack"
|Return(value)->
match stack with
|[]->Result(value)
|x::xs -> inner xs (x value)
//pushes a new value on the the "Stack"
|StackPush(ret,next) ->
inner (ret::stack) next
//performs a single step
|Continuation(fn)->
inner stack (fn()))
inner []
Here is a brief example of the two types in action.
let run<'t> :'t StackFree->'t =
let rec inner = function
|Step(x)-> inner (x())
|Result(x)-> x
stackFreeToRunning>>inner
//silly function to recompute an intiger value using recursion
let rec recompute number = stackfree {
if number = 0 then return 0
else
let! next = recompute (number-1)
return next+1
}
let stackFreeValue = recompute 100000
let result = run stackFreeValue
do printfn "%i" result
I have spent several hours trying to get a Computation Expression that works directly on the Running type and cutting out the middleman StackFree. However I cannot figure out how to do it. At this point I am seriously considering the possibility that a solution to this problem is impossible. However I cannot figure out the reason that it is impossible.
I have gotten close a few times but the resulting solutions ended up using the stack in some confusing way.
Is it possible to have a computation expression that operates on the Running type without utilizing the .Net stack? If this is not possible why is it not possible. There must be some simple mathematical reasoning that I am missing.
NB: These are not the actual types I am using they are simplified for this questions the real ones keep track of scope and position in the script. Furthermore I am aware of the serious performance cost of this type of abstraction
Edit: Here is another way to approach the problem. This implementation is flawed because it uses the stack. Is there anyway to get the exact behavior below without using the stack?
type RunningMonad() =
member this.Delay(fn) =
Step(fun ()->fn ())
member this.Bind(m, fn) =
Step(fun ()->
match m with
|Result(value)-> fn value
//Here is the problem
|Step(next)-> this.Bind(next(),fn))
member this.Return(v) =
Result(v)
member this.ReturnFrom(x) = x
The bind implementation in the above computation expression creates a function that calls another function. So as you go deeper and call bind more and more you have to chase a bunch of function calls and then eventually you hit a stackoverflow exception.
Edit2: Clarity.
Better late than never!
This is addressed in section 4 of Stackless Scala with Free Monads. Bjarnason tackles the problem by adding a new constructor to the Trampoline datatype, representing a subroutine call to another trampoline. He keeps this new constructor private, in order to ensure that you can't build left-nested Binds (which would overflow the stack when executing the trampoline).
I am by no means an F#er, but I'll muddle through. In WishF#ul, an imaginary dialect of F# which I just made up, you can express the new existentially quantified constructor directly:
type Tram<'a> =
| Done of 'a
| Step of (unit -> Tram<'a>)
| Call<'x> of Tram<'x> * ('x -> Tram<'a>) // don't export this
type TramMonad() =
member this.Return(x) = Done(x)
member this.Bind(ma, f) = match ma with
| Call(mx, k) -> Call(mx, fun x -> this.Bind(k(x), f))
| _ -> Call(ma, f)
// i confess to not quite understanding what your Delay and ReturnFrom methods are for
let tram = new TramMonad()
let rec runTram t =
let next mx f = match mx with
| Done(x) -> f x
| Step(k) -> Step(fun () -> tram.Bind(k(), f))
| Call(my, g) -> tram.Bind(my, fun x -> tram.Bind(g x, f))
match t with
| Done(x) -> x
| Step(k) -> runTram(k())
| Call(mx, f) -> runTram(next mx f)
Note that all of the recursive calls to runTram are in tail position. It takes a bit of puzzling, but you can convince yourself that Bind won't construct a deeply-nested continuation, so runT will always operate in O(1) stack space.
Sadly we're working in F#, not WishF#ul, so we have to resort to an object-oriented encoding of the existential type in the Call constructor. Here goes...
module rec Trampoline =
type Call<'a> =
abstract member Rebind<'b> : ('a -> Tram<'b>) -> Tram<'b>
abstract member Next : unit -> Tram<'a>
type Tram<'a> =
| Done of 'a
| Step of (unit -> Tram<'a>)
| Call of Call<'a>
type TramMonad() =
member this.Return(x) = Done(x)
member this.Bind(ma, f) =
match ma with
| Call(aCall) -> aCall.Rebind(f)
| _ -> call ma f
let tram = new TramMonad()
let rec call<'a, 'x>(mx : Tram<'x>) (f : 'x -> Tram<'a>) : Tram<'a> = Call {
new Call<'a> with
member this.Rebind<'b>(g : 'a -> Tram<'b>) : Tram<'b> =
call<'b, 'x> mx (fun x -> tram.Bind(f x, g) : Tram<'b>)
member this.Next() =
match mx with
| Done(x) -> f x
| Step(k) -> Step(fun () -> tram.Bind(k(), f))
| Call(aCall) -> aCall.Rebind(f)
}
let rec runTram t =
match t with
| Done(x) -> x
| Step(k) -> runTram(k())
| Call(aCall) -> runTram(aCall.Next())
I recommend reading the whole paper, which goes on to generalise this stackless construction to any free monad, not just trampolines (which are Free (Unit -> _)). Phil Freeman's Stack Safety for Free builds on this work, generalising the trampoline paper's free monad to a free monad transformer.

F# - function order [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to have two methods calling each other?
I need to write 2 functions that call each other.
(with conditions inside - so they'd eventually stop)
let x () : int =
...
if (------) then
y num
...
let y () : int =
...
if (------) then
x num
...
The problem is that, as I understand it, F# evaluates functions by order of appearance.. so writing this will create compilation errors...
Is there a way to solve this problem?
So both functions will know each other?
You need the and keyword for mutually-recursive functions:
let rec x num =
...
if (------) then
y num
...
and y num =
...
if (------) then
x num
...

error with f# generic follow Expert Fsharp book example

I'm reading Expert F# book and I found this code
open System.Collections.Generic
let divideIntoEquivalenceClasses keyf seq =
// The dictionary to hold the equivalence classes
let dict = new Dictionary<'key,ResizeArray<'T>>()
// Build the groupings
seq |> Seq.iter (fun v ->
let key = keyf v
let ok,prev = dict.TryGetValue(key)
if ok then prev.Add(v)
else let prev = new ResizeArray<'T>()
dict.[key] <- prev
prev.Add(v))
dict |> Seq.map (fun group -> group.Key, Seq.readonly group.Value)
and the example use:
> divideIntoEquivalenceClasses (fun n -> n % 3) [ 0 .. 10 ];;
val it : seq<int * seq<int>>
= seq [(0, seq [0; 3; 6; 9]); (1, seq [1; 4; 7; 10]); (2, seq [2; 5; 8])]
first for me this code is really ugly, even if this is safe, It looks more similar to imperative languages than to functional lang..specially compared to clojure. But the problem is not this...I'm having problems with the Dictionary definition
when I type this:
let dict = new Dictionary<'key,ResizeArray<'T>>();;
I get this:
pruebafs2a.fs(32,5): error FS0030: Value restriction. The value 'dict' has been inferred to have generic type
val dict : Dictionary<'_key,ResizeArray<'_T>> when '_key : equality
Either define 'dict' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
is It ok?...
thanks so much
improve question:
Ok I've been reading about value restriction and I found this helpfull information
In particular, only function definitions and simple immutable data
expressions are automatically generalized
...ok..this explains why
let dict = new Dictionary<'key,ResizeArray<'T>>();;
doesn't work...and show 4 different techniques, although in my opinion they only resolve the error but aren't solutions for use generic code:
Technique 1: Constrain Values to Be Nongeneric
let empties : int list [] = Array.create 100 []
Technique 3: Add Dummy Arguments to Generic Functions When Necessary
let empties () = Array.create 100 []
let intEmpties : int list [] = empties()
Technique 4: Add Explicit Type Arguments When Necessary (similar to tec 3)
let emptyLists = Seq.init 100 (fun _ -> [])
> emptyLists<int>;;
val it : seq<int list> = seq [[]; []; []; []; ...]
----- and the only one than let me use real generic code ------
Technique 2: Ensure Generic Functions Have Explicit Arguments
let mapFirst = List.map fst //doesn't work
let mapFirst inp = List.map fst inp
Ok, in 3 of 4 techniques I need resolve the generic code before can work with this...now...returning to book example...when the compile knows the value for 'key and 'T
let dict = new Dictionary<'key,ResizeArray<'T>>()
in the scope the code is very generic for let key be any type, the same happen with 'T
and the biggest dummy question is :
when I enclose the code in a function (technique 3):
let empties = Array.create 100 [] //doesn't work
let empties () = Array.create 100 []
val empties : unit -> 'a list []
I need define the type before begin use it
let intEmpties : int list [] = empties()
for me (admittedly I'm a little dummy with static type languages) this is not real generic because it can't infer the type when I use it, I need define the type and then pass values (not define its type based in the passed values) exist other way define type without be so explicit..
thanks so much..really appreciate any help
This line
let dict = new Dictionary<'key,ResizeArray<'T>>();;
fails because when you type the ;; the compiler doesn't know what 'key and 'T are. As the error message states you need to add a type annotation, or allow the compiler to infer the type by using it later or make it a function
Examples
Type annotation change
let dict = new Dictionary<int,ResizeArray<int>>();;
Using types later
let dict = new Dictionary<'key,ResizeArray<'T>>()
dict.[1] <- 2
using a function
let dict() = new Dictionary<'key,ResizeArray<'T>>();;
This actually doesn't cause an issue when it's defined all together. That is, select the entire block that you posted and send it to FSI in one go. I get this:
val divideIntoEquivalenceClasses :
('T -> 'key) -> seq<'T> -> seq<'key * seq<'T>> when 'key : equality
However, if you type these individually into FSI then as John Palmer says there is not enough information in that isolated line for the interpreter to determine the type constraints. John's suggestions will work, but the original code is doing it correctly - defining the variable and using it in the same scope so that the types can be inferred.
for me this code is really ugly, even if this is safe, It looks more similar to imperative languages than to functional lang.
I agree completely – it's slightly tangential to your direct question, but I think a more idiomatic (functional) approach would be:
let divideIntoEquivalenceClasses keyf seq =
(System.Collections.Generic.Dictionary(), seq)
||> Seq.fold (fun dict v ->
let key = keyf v
match dict.TryGetValue key with
| false, _ -> dict.Add (key, ResizeArray(Seq.singleton v))
| _, prev -> prev.Add v
dict)
|> Seq.map (function KeyValue (k, v) -> k, Seq.readonly v)
This allows sufficient type inference to obviate the need for your question in the first place.
The workarounds proposed by the other answers are all good. Just to clarify based on your latest updates, let's consider two blocks of code:
let empties = Array.create 100 []
as opposed to:
let empties = Array.create 100 []
empties.[0] <- [1]
In the second case, the compiler can infer that empties : int list [], because we are inserting an int list into the array in the second line, which constrains the element type.
It sounds like you'd like the compiler to infer a generic value empties : 'a list [] in the first case, but this would be unsound. Consider what would happen if the compiler did that and we then entered the following two lines in another batch:
empties.[0] <- [1] // treat 'a list [] as int list []
List.iter (printfn "%s") empties.[0] // treat 'a list [] as string list []
Each of these lines unifies the generic type parameter 'a with a different concrete type (int and string). Either of these unifications is fine in isolation, but they are incompatible with each other and would result in treating the int value 1 inserted by the first line as a string when the second line is executed, which is clearly a violation of type safety.
Contrast this with an empty list, which really is generic:
let empty = []
Then in this case, the compiler does infer empty : 'a list, because it's safe to treat empty as a list of different types in different locations in your code without ever impacting type safety:
let l1 : int list = empty
let l2 : string list = empty
let l3 = 'a' :: empty
In the case where you make empties the return value of a generic function:
let empties() = Array.create 100 []
it is again safe to infer a generic type, since if we try our problematic scenario from before:
empties().[0] <- [1]
List.iter (printfn "%s") (empties().[0])
we are creating a new array on each line, so the types can be different without breaking the type system.
Hopefully this helps explain the reasons behind the limitation a bit more.

Resources