kll : Float
kll =
let
half x =
x / 2
in
List.sum (List.map half (List.map toFloat (List.range 1 10)))
converting using |>
can you also explain how to use the |> correctly with some examples cant find any online?
Thanks
This is my code:
kll : List Float
kll =
let
half x =
x / 2
in
((1 |> 1 |> List.range) |> toFloat |> List.map) (|>half |> List.map))|> List.sum
|> doesn't work with 2-parameter functions. It only feeds into functions that take one parameter.
Use currying to supply leading parameters. I think what you want is this:
List.range 1 10 |> List.map toFloat |> List.map half |> List.sum
Or more simply:
List.range 1 10 |> List.map (\x -> toFloat x / 2) |> List.sum
Related
I am new to F# and I am trying to make a function called sumUp that adds 2 values like 1+2.
But I want it to work on an array, I tried the code you see in the snippit, but it doesnt seem to work, what am I doing wrong and why isn't this working?
let sumUp int1 int2 = int1 + int2
let numbers = [1;2;3]
numbers |> Seq.map (sumUp 4)
my expected result is [5,6,7] but i dont get any result at all.
This is my output:
- let sumUp int1 int2 = int1 + int2
-
- let numbers = [1;2;3]
-
- let result = numbers |> Seq.map (sumUp 4)
- ;;
val sumUp: int1: int -> int2: int -> int
val numbers: int list = [1; 2; 3]
val result: seq<int>
Your code is correct. The only problem is that Seq.map is a lazy function, so the value of result is just seq<int> until you do something to enumerate the sequence. You can do this using printfn, for example:
> let result = numbers |> Seq.map (sumUp 4);;
val result: seq<int>
> printfn "%A" result;;
seq [5; 6; 7]
Alternatively, you could use List.map instead of Seq.map to avoid lazy evaluation in the first place:
> let result = numbers |> List.map (sumUp 4);;
val result: int list = [5; 6; 7]
Note that your input ([1;2;3]) is a list, not an array. If you want to use arrays instead, try this:
> let numbers = [|1;2;3|];;
val numbers: int[] = [|1; 2; 3|]
> let result = numbers |> Array.map (sumUp 4);;
val result: int[] = [|5; 6; 7|]
I am trying to generate a list of even integers while the sum of the items in the list is less equal a given number.
For instance if the threshold k is 20, then the expected output is [0;2;4;6;8]
I can generate a list where the largest value is smaller by the threshold like this:
let listOfEvenNumbersSmallerThanTwenty =
Seq.unfold (fun x -> Some(x, x + 1)) 0 // natural numbers
|> Seq.filter (fun x -> x % 2 = 0) // even numbers
|> Seq.takeWhile (fun x -> x <= 20)
|> List.ofSeq
(I know that I can combine the unfold and filter to Some(x, x + 2) but this task is for educational purposes)
I managed to create a different list with a running total smaller than the threshold:
let runningTotal =
listOfEvenNumbersSmallerThanTwenty
|> Seq.scan (+) 0
|> Seq.filter (fun x -> x < 20)
|> List.ofSeq
But in order to do that, I have set the threshold in listOfEvenNumbersSmallerThanTwenty (which is way more than the items needed) and I have lost the initial sequence. I did also try to find that using a mutable value but didn't really like that route.
You can create a small predicate function that will encapsulate a mutable sum.
let sumLessThan threshold =
let mutable sum = 0
fun x ->
sum <- sum + x
sum < threshold
Usage is very simple and it can be applied to any sequence
Seq.initInfinite ((*) 2) |> Seq.takeWhile (sumLessThan 20)
There is nothing bad in using mutable state when its encapsulated (check usages of the mutable variable in Seq module)
Here's a solution that I think is pretty elegant (although not the most efficient):
let evens = Seq.initInfinite (fun i -> 2 * i)
Seq.initInfinite (fun i -> Seq.take i evens)
|> Seq.takeWhile (fun seq ->
Seq.sum seq <= 20)
|> Seq.last
|> List.ofSeq
As a tutoring exercise I implemented the Knights Tour algorithm in CS and worked fine, after trying to port it to F# I cannot go past the part where I aggregate the resulting sequences of the Knight's path to return to the caller.
The code is this:
let offsets = [|(-2,-1);(-2,1);(-1,-2);(-1,2);(1,-2);(1,2);(2,-1);(2,1)|];
let squareToPair sqr =
(sqr % 8, sqr / 8)
let pairToSquare (col, row) =
row * 8 + col
// Memoizing function taken from Don Syme (http://blogs.msdn.com/b/dsyme/archive/2007/05/31/a-sample-of-the-memoization-pattern-in-f.aspx)
let memoize f =
let cache = ref Map.empty
fun x ->
match (!cache).TryFind(x) with
| Some res -> res
| None ->
let res = f x
cache := (!cache).Add(x,res)
res
let getNextMoves square =
let (col, row) = squareToPair square
offsets
|> Seq.map (fun (colOff, rowOff) -> (col + colOff, row + rowOff))
|> Seq.filter (fun (c, r) -> c >= 0 && c < 8 && r >= 0 && r < 8) // make sure we don't include squares out of the board
|> Seq.map (fun (c, r) -> pairToSquare (c, r))
let getNextMovesMemoized = memoize getNextMoves
let squareToBoard square =
1L <<< square
let squareToBoardMemoized = memoize squareToBoard
let getValidMoves square board =
getNextMovesMemoized square
|> Seq.filter (fun sqr -> ((squareToBoardMemoized sqr) &&& board) = 0L)
// gets all valid moves from a particular square and board state sorted by moves which have less next possible moves
let getValidMovesSorted square board =
getValidMoves square board
|> Seq.sortBy (fun sqr -> (getValidMoves sqr board) |> Seq.length )
let nextMoves = getValidMovesSorted
let sqrToBoard = squareToBoardMemoized
let findPath square =
let board = sqrToBoard square
let rec findPathRec brd sqr sequence = seq {
match brd with
| -1L -> yield sequence
| _ -> for m in nextMoves sqr do yield! findPathRec (brd ||| (sqrToBoard m)) m m::sequence
}
findPathRec board square [square]
let solution = findPath ((4,4) |> pairToSquare) |> Seq.take 1
I am getting the following error:
The type '(int64 -> seq<int>)' is not a type whose values can be enumerated with this syntax, i.e. is not compatible with either seq<_>, IEnumerable<_> or IEnumerable and does not have a GetEnumerator method (using external F# compiler)
I could probably be misunderstanding how this work, but I would expect the results of nextMoves to be seq<_>. Is there a better way of doing this? Am I missing something? Any recommended patterns?
Thanks in advance!
So the problem is that nextMoves has type
val nextMoves : (int -> int64 -> seq<int>)
because it is identical to getValidMovesSorted. You need to supply the board argument
nextMoves is just getValidMovesSorted which takes two arguments (square and board) - now in findPath you only provided one and I guess you wanted to write this
nextMoves sqr board
but then there are more issues in the rest of the code and it's really hard to figure out what you are trying to do
I think you wanted to do something like this:
let findPath square =
let board = sqrToBoard square
let rec findPathRec brd sqr (sequence : int list) =
match brd with
| -1L -> sequence
| _ ->
[
for m in nextMoves sqr board do
yield! findPathRec (brd ||| (sqrToBoard m)) m (m::sequence)
]
this will compile (but will result in an stack-overflow exception)
I am doing some exercises on F#, i have this function that calculate the alternate sum:
let rec altsum = function
| [] -> 0
| [x] -> x
| x0::x1::xs -> x0 - x1 + altsum xs;;
val altsum : int list -> int
The exercise consist in declare the same function with only two clauses...but how to do this?
The answer of mydogisbox is correct and work!
But after some attempts I found a smallest and readable solution of the problem.
let rec altsum2 = function
| [] -> 0
| x0::xs -> x0 - altsum2 xs
Example
altsum2 [1;2;3] essentially do this:
1 - (2 - (3 - 0)
it's is a bit tricky but work!
OFF TOPIC:
Another elegant way to solve the problem, using F# List library is:
let altsum3 list = List.foldBack (fun x acc -> x - acc) list 0;;
After the comment of phoog I started trying to solve the problem with a tail recursive function:
let tail_altsum4 list =
let pl l = List.length l % 2 = 0
let rec rt = function
| ([],acc) -> if pl list then -acc else acc
| (x0::xs,acc) -> rt (xs, x0 - acc)
rt (list,0)
This is also a bit tricky...substraction is not commutative and it's impossible think to revers with List.rev a long list...but I found a workaround! :)
To reduce the number of cases, you need to move your algorithm back closer to the original problem. The problem says to negate alternating values, so that's what your solution should do.
let altsum lst =
let rec altsumRec lst negateNext =
match lst with
| [] -> 0
| head::tail -> (if negateNext then -head else head) + altsumRec tail (not negateNext)
altsumRec lst false
I'm doing some homework but I've been stuck for hours on something.
I'm sure it's really trivial but I still can't wrap my head around it after digging through the all documentation available.
Can anybody give me a hand?
Basically, the exercise in OCaml programming asks to define the function x^n with the exponentiation by squaring algorithm.
I've looked at the solution:
let rec exp x = function
0 -> 1
| n when n mod 2 = 0 -> let y = exp x (n/2) in y*y
| n when n mod 2 <> 0 -> let y = exp x ((n-1)/2) in y*y*x
;;
What I don't understand in particular is how the parameter n can be omitted from the fun statement and why should it be used as a variable for a match with x, which has no apparent link with the definition of exponentiation by squaring.
Here's how I would do it:
let rec exp x n = match n with
0 -> 1
| n when (n mod 2) = 1 -> (exp x ((n-1)/2)) * (exp x ((n-1)/2)) * x
| n when (n mod 2) = 0 -> (exp x (n/2)) * (exp x (n/2))
;;
Your version is syntaxically correct, yields a good answer, but is long to execute.
In your code, exp is called recursively twice, thus yielding twice as much computation, each call yielding itself twice as much computation, etc. down to n=0. In the solution, exp is called only once, the result is storred in the variable y, then y is squared.
Now, about the syntax,
let f n = match n with
| 0 -> 0
| foo -> foo-1
is equivalent to:
let f = function
| 0 -> 0
| foo -> foo-1
The line let rec exp x = function is the begging of a function that takes two arguments: x, and an unnammed argument used in the pattern matching. In the pattern matching, the line
| n when n mod 2 = 0 ->
names this argument n. Not that a different name could be used in each case of the pattern matching (even if that would be less clear):
| n when n mod 2 = 0 -> let y = exp x (n/2) in y*y
| p when p mod 2 <> 0 -> let y = exp x ((p-1)/2) in y*y*x
The keyword "function" is not a syntaxic sugar for
match x with
but for
fun x -> match x with
thus
let rec exp x = function
could be replaced by
let rec exp x = fun y -> match y with
which is of course equivalent with your solution
let rec exp x y = match y with
Note that i wrote "y" and not "n" to avoid confusion. The n variable introduced after the match is a new variable, which is only related to the function parameter because it match it. For instance, instead of
let y = x in ...
you could write :
match x with y -> ...
In this match expression, the "y" expression is the "pattern" matched. And like any pattern, it binds its variables (here y) with the value matched. (here the value of x) And like any pattern, the variables in the pattern are new variables, which may shadow previously defined variables. In your code :
let rec exp x n = match n with
0 -> 1
| n when (n mod 2) = 1 -> (exp x ((n-1)/2)) * (exp x ((n-1)/2)) * x
| n when (n mod 2) = 0 -> (exp x (n/2)) * (exp x (n/2))
;;
the variable n in the two cases shadow the parameter n. This isn't a problem, though, since the two variable with the same name have the same value.