In F#, I receive an error when I write the following code:
let records = {1..100}
let middleElement= records |> Seq.length / 2
The type 'int' does not match the type ''a -> int'
I know this error is basic.
But I'm new to F# and really don't know what I need to do to resolve this error.
You need to add parentheses:
let middleElement = (records |> Seq.length) / 2
In your version, the compiler reads your code as
let middleElement = records |> (Seq.length / 2)
... and it gets confused, because it thinks you are trying to divide the length function by 2!
I endorse Tomas Petricek's answer, but you could also write it this way. :-)
let records = {1..100}
let middleElement = records |> Seq.length |> (/) <| 2
This says, take the records, feed them to the length function. Feed the result as the first argument to the divide (/) function. This will result in a function which takes an int and returns an int (int -> int). We then feed 2 to that function to get 50.
[Edit] I just realized that this might be even clearer
let records = {1..100}
let middleElement = let length = records |> Seq.length in length / 2;;
Related
I am looking for a type similar to sequences in F# where indices could be big integers, rather that being restricted to int. Does there exist anything like this?
By "big integer indices" I mean a type which allows for something equivalent to that:
let s = Seq.initInfinite (fun i -> i + 10I)
The following will generate an infinite series of bigints:
let s = Seq.initInfinite (fun i -> bigint i + 10I)
What i suspect you actually want though is a Map<'Key, 'Value>.
This lets you efficiently use a bigint as an index to look up whatever value it is you care about:
let map =
seq {
1I, "one"
2I, "two"
3I, "three"
}
|> Map.ofSeq
// val map : Map<System.Numerics.BigInteger,string> =
// map [(1, "one"); (2, "two"); (3, "three")]
map.TryFind 1I |> (printfn "%A") // Some "one"
map.TryFind 4I |> (printfn "%A") // None
The equivalent of initInfinite for BigIntegers would be
let inf = Seq.unfold (fun i -> let n = i + bigint.One in Some(n, n)) bigint.Zero
let biggerThanAnInt = inf |> Seq.skip (Int32.MaxValue) |> Seq.head // 2147483648
which takes ~2 min to run on my machine.
However, I doubt this is of any practical use :-) That is unless you start at some known value > Int32.MaxValue and stop reasonably soon (generating less than Int32.MaxValue items), which then could be solved by offsetting the BigInt indexes into the Int32 domain.
Theoretically you could amend the Seq module with functions working with BigIntegers to skip / window / ... an amount of items > Int32.MaxValue (e.g. by repeatedly performing the corresponding Int32 variant)
Since you want to index into a sequence, I assume you want a version of Seq.item that takes a BigInteger as index. There's nothing like that built into F#, but it's easy to define your own:
open System.Numerics
module Seq =
let itemI (index : BigInteger) source =
source |> Seq.item (int index)
Note that no new type is needed unless you're planning to create sequences that are longer than 2,147,483,647 items, which would probably not be practical anyway.
Usage:
let items = [| "moo"; "baa"; "oink" |]
items
|> Seq.itemI 2I
|> printfn "%A" // output: "oink"
I'm working on a homework assignment. And I'm trying to learn F# so I don't want any shortcuts besides using basic things like List.Map or lambdas or something.
I'm trying to process a list of tuples, but I'm having trouble accessing the tuples in the list.
I want to take the list of tuples, add up the numbers in each tuple, and return that number, printing it out each time.
let listTup = [(2,3,4); (4,5,6); (6,7,8)]
let getSum (a,b,c) =
a+b+c
let rec printSum tpList =
let total = 0
match tpList with
| [] -> total //return 0 if empty list
| hd::tl ->
print (getSum hd)
The first thing you want to do is map your tuples through the getSum function. This can be done very simply by piping the list of tuples into List.map getSum. Then you want to print each element in the list, so you pipe the result of List.map getSum into List.iter with the function printfn "%d". This works because of the functions having curried parameters. printfn "%d" applies the "%d" parameter to printfn and returns a function taking an integer, which it then prints. The whole thing would look like this:
let listTup = [(2,3,4); (4,5,6); (6,7,8)]
let getSum (a,b,c) =
a + b + c
let printSum tpList =
tpList |> List.map getSum |> List.iter (printfn "%d")
This prints:
9
15
21
We can even simplify the function further if we take advantage of function composition (the >> operator). Notice that printSum takes tpList as its parameter, and then just uses it as input to two functions that are pipelined together. Since pipelining just takes the output of one function and passes it as the last parameter of another function, all we really need to do is compose the function List.map getSum, which takes a list of int 3-tuples and returns a list of ints with List.iter (printfn "%d"), which takes a list of ints and returns unit. That would look like this:
let printSum = List.map getSum >> List.iter (printfn "%d")
This will print the same results, but is a simpler way of expressing the function.
F# has imperative loops as well. In this case I think an imperative loop matches the problem most idiomatically.
let listTup = [(2,3,4); (4,5,6); (6,7,8)]
for a,b,c in listTup do
let sum = a + b + c
printfn "%d" sum
I'm new on F#, and can't see how extract the int value from:
let autoInc = FsCheck.Gen.choose(1,999)
The compiler say the type is Gen<int>, but can't get the int from it!. I need to convert it to decimal, and both types are not compatible.
From a consumer's point of view, you can use the Gen.sample combinator which, given a generator (e.g. Gen.choose), gives you back some example values.
The signature of Gen.sample is:
val sample : size:int -> n:int -> gn:Gen<'a> -> 'a list
(* `size` is the size of generated test data
`n` is the number of samples to be returned
`gn` is the generator (e.g. `Gen.choose` in this case) *)
You can ignore size because Gen.choose ignores it, as its distribution is uniform, and do something like:
let result = Gen.choose(1,999) |> Gen.sample 0 1 |> Seq.exactlyOne |> decimal
(* 0 is the `size` (gets ignored by Gen.choose)
1 is the number of samples to be returned *)
The result should be a value in the closed interval [1, 999], e.g. 897.
Hi to add to what Nikos already told you, this is how you can get an decimal between 1 and 999:
#r "FsCheck.dll"
open FsCheck
let decimalBetween1and999 : Gen<decimal> =
Arb.generate |> Gen.suchThat (fun d -> d >= 1.0m && d <= 999.0m)
let sample () =
decimalBetween1and999
|> Gen.sample 0 1
|> List.head
you can now just use sample () to get a random decimal back.
In case you just want integers between 1 and 999 but have those converted to decimal you can just do:
let decimalIntBetween1and999 : Gen<decimal> =
Gen.choose (1,999)
|> Gen.map decimal
let sampleInt () =
decimalIntBetween1and999
|> Gen.sample 0 1
|> List.head
what you probably really want to do instead
Is use this to write you some nice types and check properties like this (here using Xunit as a test-framework and the FsCheck.Xunit package:
open FsCheck
open FsCheck.Xunit
type DecTo999 = DecTo999 of decimal
type Generators =
static member DecTo999 =
{ new Arbitrary<DecTo999>() with
override __.Generator =
Arb.generate
|> Gen.suchThat (fun d -> d >= 1.0m && d <= 999.0m)
|> Gen.map DecTo999
}
[<Arbitrary(typeof<Generators>)>]
module Tests =
type Marker = class end
[<Property>]
let ``example property`` (DecTo999 d) =
d > 1.0m
Gen<'a> is a type that essentially abstracts a function int -> 'a (the actual type is a bit more complex, but let's ignore for now). This function is pure, i.e. when given the same int, you'll get the same instance of 'a back every time. The idea is that FsCheck generates a bunch of random ints, feeds them to the Gen function, out come random instances of the type 'a you're interested in, and feeds those to a test.
So you can't really get out the int. You have in your hands a function that given an int, generates another int.
Gen.sample as described in another answer essentially just feeds a sequence of random ints to the function and applies it to each, returning the results.
The fact that this function is pure is important because it guarantees reproducibility: if FsCheck finds a value for which a test fails, you can record the original int that was fed into the Gen function - rerunning the test with that seed is guaranteed to generate the same values, i.e. reproduce the bug.
I am trying to fill a list with random numbers and am having diffculty getting the random number part. What I have right now prints out a random number 10 times, what I want is to print out 10 different random numbers
let a = (new System.Random()).Next(1, 1000)
let listOfSquares = [ for i in 1 .. 10->a]
printfn "%A" listOfSquares
any tips or suggestions?
Your code is simply getting one random number and using it ten times.
This extension method might be useful:
type System.Random with
/// Generates an infinite sequence of random numbers within the given range.
member this.GetValues(minValue, maxValue) =
Seq.initInfinite (fun _ -> this.Next(minValue, maxValue))
Then you can use it like this:
let r = System.Random()
let nums = r.GetValues(1, 1000) |> Seq.take 10
let genRandomNumbers count =
let rnd = System.Random()
List.init count (fun _ -> rnd.Next ())
let l = genRandomNumbers 10
printfn "%A" l
When I write a random something dispenser I like to use the same random number generator for each call to the dispenser. You can do that in F# with closures (a combination of Joel's and ildjarn's answer).
Example:
let randomWord =
let R = System.Random()
fun n -> System.String [|for _ in 1..n -> R.Next(26) + 97 |> char|]
In this way, a single instance of Random is 'baked into' the function, reusing it with each call.
There are two problems:
1) In F# functions are supposed to be pure so a function without arguments is considered as final value.
To declare impure function "without arguments", let it take one argument of type unit
let a () = (new System.Random()).Next(1, 1000)
and call it passing unit argument
let list = [ for i in 1 .. 10 -> a () ]
Source
2) New System.Random() instance is created each time when a is called. This results in getting same numbers. To fix this, create the instance only once
let random = new System.Random()
let a () = random.Next(1, 1000)
let list = [ for i in 1 .. 10 -> a ()]
This isn't specific to F#, read explanation for C# for better understanding
You could also avoid declaring an impure function as said by Pavel and just run:
let rnd = Random()
let rndList = [for i in 0..100 do rnd.Next(1000)]
I think one should be careful how to initialize System.Random as it uses the current time as seed. One instance should be enough for the whole app. Injecting random into functions has the advantage that you can use a fixed seed and reproduce with semi randomness, e.g. for testing your logic.
let rnd = System.Random()
let genRandomNumbers random count =
List.init count (fun _ -> random.Next ())
let getRandomNumbersSeeded = getRandomNumbers rnd
let l = getRandomNumbersSeeded 10
printfn "%A" l
(I'm still banging on with units of measure in F#)
I'm having a problem making 'generic' functions which take 'typed' floats.
The following mockup class is intended to keep tabs on a cumulative error in position, based on a factor 'c'. The compiler doesn't like me saying 0.<'a> in the body of the type ("Unexpected type parameter in unit-of-measure literal").
///Corrects cumulative error in position based on s and c
type Corrector(s_init:float<'a>) =
let deltaS ds c = sin (ds / c) //incremental error function
//mutable values
let mutable nominal_s = s_init
let mutable error_s = 0.<'a> //<-- COMPILER NO LIKE
///Set new start pos and reset error to zero
member sc.Reset(s) =
nominal_s <- s
error_s <- 0.<'a> //<-- COMPILER NO LIKE
///Pass in new pos and c to corrector, returns corrected s and current error
member sc.Next(s:float<'a>, c:float<'a>) =
let ds = s - nominal_s //distance since last request
nominal_s <- s //update nominal s
error_s <- error_s + (deltaS ds c) //calculate cumulative error
(nominal_s + error_s, error_s) //pass back tuple
Another related question, I believe, still to do with 'generic' functions.
In the following code, what I am trying to do is make a function which will take a #seq of any type of floats and apply it to a function which only accepts 'vanilla' floats. The third line gives a 'Value Restriction' error, and I can't see any way out. (Removing the # solves the problem, but I'd like to avoid having to write the same thing for lists, seqs, arrays etc.)
[<Measure>] type km //define a unit of measure
let someFloatFn x = x + 1.2 //this is a function which takes 'vanilla' floats
let MapSeqToNonUnitFunction (x:#seq<float<'a>>) = Seq.map (float >> someFloatFn) x
let testList = [ 1 .. 4 ] |> List.map float |> List.map ((*) 1.0<km>)
MapSeqToNonUnitFunction testList
You can change the first 'compiler no like' to
let mutable error_s : float<'a> = 0.0<_>
and the compiler seems to like that.
As for the second question, I am not seeing the same error as you, and this
[<Measure>] type km
//define a unit of measure
let someFloatFn x = x + 1.2 //this is a function which takes 'vanilla' floats
let MapSeqToNonUnitFunction (x:seq<float<_>>) = Seq.map (float >> someFloatFn) x
let testList = [ 1 .. 4 ] |> List.map float |> List.map ((*) 1.0<km>)
let testList2 = testList :> seq<_>
let result = MapSeqToNonUnitFunction testList2
printfn "%A" result
compiles for me (though the upcast to seq<_> is a little annoying, I am not sure if there is an easy way to get rid of it or not).
Aside, I think convention is to name units parameters 'u, 'v, ... rather than 'a, 'b, ...
Units of measure cannot be used as type parameters. This is because the are erased by the compiler during compilation. This question is quite similar:
F# Units of measure - 'lifting' values to float<something>