I want to write a function that inserts a value v into a list on postition a. the type of the list is
type RefList<'t> = Item<'t> ref
and Item<'t> = | Nil | Cons of 't * RefList<'t>
let rec insert<'t> (a: int) (v: <'t>) (structure: RefList<'t>): unit =
and
let rec remove<'t> (a: int) (structure: RefList<'t>): unit =
I tried something like this, but Im sure im on a very wrong way
let mutable worker = 0
if a = worker then then Cons(v, !structure) else Cons(y, insert i v ys)
worker <- worker + 1
im not sure if i should do a match to |Nil and |Cons or not. the "unit" confuses me.
I hope somebody can help me, thanks!
Edit: I already have a function RefListToList and ListToRefList. this might be useful for the other functions
Related
Sorry for my question but I did not understand the answers that was related to this question so I hope someone can enlighten me further.
I am a new data science student and we are going to learn how to program in the functional language F#. We are learning about algorithms and I wanted to write the algorithms as F# functions to check if my calculations on paper were correct.
I get the following error saying:
"This value is not mutable. Consider using the mutable keyword let mutable n = expression"
My code looks like this:
let loop5( n ) =
let mutable x = 0
while n > 0 do
x <- x + 1
n <- n + 1
printfn "loop5(): x=%i for n=%i" x n
loop5(4)
I'm trying to write a function looking like this (pseudocode):
loop5(n)
x = 0
while n > 0
x = x + 1
n = n + 1
return x
Hope I made a clear question and someone can help me out here :-) Have a nice weekend
You're trying to mutate the loop's parameter n. The parameter is not mutable, so the compiler doesn't let you. That's exactly what the error tells you.
Now, normally, to make the error go away, you'd make the variable mutable. However, you can't make a function parameter mutable, so that's not an option.
Here you want to think what the meaning of your program should be. Does the loop function need to pass the updated value of n back to its caller, or is the whole mutation its internal business? If it's the former, please see #AnyMoose's answer, but from your example and explanation, I suspect it's the latter. If that is the case, simply make a mutable copy of the parameter and work with it:
let loop n' =
let mutable x = 0
let mutable n = n'
...
Separately, I want to point out that your program, as written, would actually loop indefinitely (or until it wraps around the max int value anyway), because instead of decreasing n at each step you're increasing it. If you want your program to actually finish before the next Ice Age, you need to make n decrease with each iteration:
n <- n - 1
Ref cells
Ref cells get around some of the limitations of mutables. In fact, ref cells are very simple datatypes which wrap up a mutable field in a record type. Ref cells are defined by F# as follows:
type 'a ref = { mutable contents : 'a }
The F# library contains several built-in functions and operators for working with ref cells:
let ref v = { contents = v } (* val ref : 'a -> 'a ref *)
let (!) r = r.contents (* val (!) : 'a ref -> 'a *)
let (:=) r v = r.contents <- v (* val (:=) : 'a ref -> 'a -> unit *)
The ref function is used to create a ref cell, the ! operator is used to read the contents of a ref cell, and the := operator is used to assign a ref cell a new value. Here is a sample in fsi:
let x = ref "hello";;
val x : string ref
x;; (* returns ref instance *)
val it : string ref = {contents = "hello";}
!x;; (* returns x.contents *)
val it : string = "hello"
x := "world";; (* updates x.contents with a new value *)
val it : unit = ()
!x;; (* returns x.contents *)
val it : string = "world"
Since ref cells are allocated on the heap, they can be shared across multiple functions:
open System
let withSideEffects x =
x := "assigned from withSideEffects function"
let refTest() =
let msg = ref "hello"
printfn "%s" !msg
let setMsg() =
msg := "world"
setMsg()
printfn "%s" !msg
withSideEffects msg
printfn "%s" !msg
let main() =
refTest()
Console.ReadKey(true) |> ignore
main()
The withSideEffects function has the type val withSideEffects : string ref -> unit.
This program outputs the following:
hello
world
Assigned from withSideEffects function
The withSideEffects function is named as such because it has a side-effect, meaning it can change the state of a variable in other functions. Ref Cells should be treated like fire. Use it cautiously when it is absolutely necessary but avoid it in general. If you find yourself using Ref Cells while translating code from C/C++, then ignore efficiency for a while and see if you can get away without Ref Cells or at worst using mutable. You would often stumble upon a more elegant and more maintanable algorithm
Aliasing Ref Cells
Note: While imperative programming uses aliasing extensively, this practice has a number of problems. In particular it makes programs hard to follow since the state of any variable can be modified at any point elsewhere in an application. Additionally, multithreaded applications sharing mutable state are difficult to reason about since one thread can potentially change the state of a variable in another thread, which can result in a number of subtle errors related to race conditions and dead locks.
A ref cell is very similar to a C or C++ pointer. Its possible to point to two or more ref cells to the same memory address; changes at that memory address will change the state of all ref cells pointing to it. Conceptually, this process looks like this:
Let's say we have 3 ref cells looking at the same address in memory:
Three references to an integer with value 7
cell1, cell2, and cell3 are all pointing to the same address in memory. The .contents property of each cell is 7. Let's say, at some point in our program, we execute the code cell1 := 10, this changes the value in memory to the following:
Three references to an integer with value 10
By assigning cell1.contents a new value, the variables cell2 and cell3 were changed as well. This can be demonstrated using fsi as follows:
let cell1 = ref 7;;
val cell1 : int ref
let cell2 = cell1;;
val cell2 : int ref
let cell3 = cell2;;
val cell3 : int ref
!cell1;;
val it : int = 7
!cell2;;
val it : int = 7
!cell3;;
val it : int = 7
cell1 := 10;;
val it : unit = ()
!cell1;;
val it : int = 10
!cell2;;
val it : int = 10
!cell3;;
val it : int = 10
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.
If I have a type named Person, and list of functions, for example...
let checks = [checkAge; checkWeight; checkHeight]
...where each function is of the type (Person -> bool), and I want to do the equivalent of...
checkAge >> checkWeight >> checkHeight
...but I don't know in advance what functions are in the list, how would I do it?
I tried the following...
checks |> List.reduce (>>)
...but this gives the following error...
error FS0001: Type mismatch. Expecting a
(Person -> bool) -> (Person -> bool) -> Person -> bool
but given a
(Person -> bool) -> (bool -> 'a) -> Person -> 'a
The type 'Person' does not match the type 'bool'
What am I doing wrong?
It looks like Railway oriented programming would be a good fit here.
If you choose to go this route, you basically have two options.
You can either go all in, or the quick route.
Quick route
You rewrite your validation functions to take a Person option instead of just plain Person.
let validAge (record:Record option) =
match record with
| Some rec when rec.Age < 65 && rec.Age > 18 -> record
| None -> None
Now you should be able to easily chain your function.
checks |> List.reduce (>>)
All in
Alternatively, if you are lazy and don't want to match .. with in every validation function, you can write some more code.
(samples taken from [1])
First there's a bit of setup to do.
We'll define a special return type, so we can get meaningful error messages.
type Result<'TSuccess,'TFailure> =
| Success of 'TSuccess
| Failure of 'TFailure
A bind function, to bind the validations together
let bind switchFunction =
function
| Success s -> switchFunction s
| Failure f -> Failure f
You'll have to rewrite your validation functions as well.
let validAge (record:Record) =
if record.Age < 65 && record.Age > 18 then Success input
else Failure "Not the right age bracket"
Now combine with
checks |> List.reduce (fun acc elem -> acc >> bind elem)
Either way, check out the original article.
There's much more there you might be able to use :)
Edit: I just noticed that I was too slow in writing this answer once again.
Besides, I think Helge explained the concetp better than I did as well.
You may somehow have stumbled upon a dreaded concept. Apperently its the Voldemort (dont say his name!) of functional programming.
With no further ado lets walk right into the code:
type Person =
{ Name : string
Age : int
Weight : int
Height : int }
type Result =
| Ok of Person
| Fail
let bind f m =
match m with
| Ok p -> f p
| _ -> Fail
let (>=>) f1 f2 = f1 >> (bind f2)
let checkAge p =
if p.Age > 18 then Ok(p)
else Fail
let checkWeight p =
if p.Weight < 80 then Ok(p)
else Fail
let checkHeight p =
if p.Height > 150 then Ok(p)
else Fail
let checks = [ checkAge; checkWeight; checkHeight ]
let allcheckfunc = checks |> List.reduce (>=>)
let combinedChecks =
checkAge
>=> checkWeight
>=> checkHeight
let p1 =
{ Name = "p1"
Age = 10
Weight = 20
Height = 110 }
let p2 =
{ Name = "p2"
Age = 19
Weight = 65
Height = 180 }
allcheckfunc p1
combinedChecks p1
allcheckfunc p2
combineChecks p2
At this point I could throw around a lot of weirdo lingo (not really true, I couldnt...), but lets just look at what I have done.
I dropped your return value of bool and went for another type (Result) with either (mark that keyword!) Ok or Fail.
Then made a helper (bind) to wrap and unwrapp stuff from that Result-type.
And a new operator (>=>) to combine the stuff in reduce.
Mind that the first check-function to Fail will shortcut the entire chain and more or less immediately (not calling the other functions) return Fail. In addition you will not know where in this chain it did Fail or which functions ahead of any Fail did actually Ok.
There are methods to also accumulate the errors as you go along, so that you get get a feedback of type: "the checkAge returned Fail, but the others was great success"
The code is mostly stolen from here: http://fsharpforfunandprofit.com/posts/recipe-part2/
And you may want to read about the entire website of Wlaschin and even a lot more to get into the finer and harder details if wanted.
Good luck on your journey to the upper floors of the Ivory Tower. ;-)
Footnote: This is called an Either-monad usually. Its not entirely finished and what not in the above code, but never mind... I think it will work in your case...
The >> operator is useful if you have functions that perform some transformation. For example, if you had a list of functions Person -> Person that turn one person into another.
In your case, it seems that you have functions Person -> bool and you want to build a composed function that returns true if all functions return true.
Using List.reduce you can write:
checks|> List.reduce (fun f g -> (fun p -> f p && g p))
Perhaps an easier option is to just write a function that takes a person and uses List.forall:
let checkAll checks person = checks |> List.forall (fun f -> f person)
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.
I'm wondering what others have come up with for dealing with Nullable<'T> in F#. I want to use Nullable<'T> on data types so that serialization works properly (i.e., doesn't write out F# option type to XML). But, I don't want my code stuck dealing with the ugliness of dealing with Nullable<'T> directly. Any suggestions?
Is it better to use active patterns to match directly on Nullable, or just a converter to option and use Some/None matching?
Additionally, I'd love to hear ideas on dealing with nullable references in a nice manner too. If I use, say "string option", then I end up with the F# option type wrapping things. If I don't then I can't distinguish between truly optional strings and strings that shouldn't be null.
Any chance .NET 4 will take on an Option<'T> to help out? (If it's part of the BCL, then we might see better support for it...)
As active patterns as options plays nicely with pattern matching, but is seems by using active patterns (i.e. typeof and ??) your code will eat more ticks.
The base question is how you will deal with your nullable references?
In case your code is long chained computations it's nice to use monadic syntax:
type Maybe<'a> = (unit -> 'a option)
let succeed x : Maybe<'a> = fun () -> Some(x)
let fail : Maybe<'a> = fun () -> None
let run (a: Maybe<'a>) = a()
let bind p rest = match run p with None -> fail | Some r -> (rest r)
let delay f = fun () -> run (f ())
type MaybeBuilder() =
member this.Return(x) = succeed x
member this.Let(p,rest) = rest p
member this.Bind(p,rest) = bind p rest
member this.Delay(f) = delay f
let maybe = new MaybeBuilder()
let add (a:'a) (b:'a) =
maybe {
match TryGetNumericAssociation<'a>() with
| Some v -> return (v.Add(a,b))
| _ -> return! fail
}
let add3 (a:'a) (b:'a) (c:'a) =
maybe {
let! ab = add a b
let! abc = add ab c
return abc
}
> let r1 = add 1 2;;
val r1 : (unit -> int option)
> r1();;
val it : int option = Some 3
> let r2 = add "1" "2";;
val r2 : (unit -> string option)
> r2();;
val it : string option = None
> let r3 = add3 "one" "two" "three";;
val r3 : (unit -> string option)
> r3();;
val it : string option = None