I have a sequence of value that I would like to apply to a function partially :
let f a b c d e= a+b+c+d+e
let items = [1,2,3,4,5]
let result = applyPartially f items
Assert.Equal(15, result)
I am looking after the applyPartially function. I have tried writing recursive functions like this :
let rec applyPartially f items =
| [] -> f
| [x] -> f x
| head :: tail -> applyPartially (f head) tail
The problem I have encountered is that the f type is at the beginning of my iteration 'a->'b->'c->'d->'e, and for every loop it should consume an order.
'a->'b->'c->'d->'e
'b->'c->'d->'e
'c->'d->'e
'd->'e
That means that the lower interface I can think of would be 'd->'e. How could I hide the complexity of my function so that only 'd->'e is shown in the recursive function?
The F# type system does not have a nice way of working with ordinary functions in a way you are suggesting - to do this, you'd need to make sure that the length of the list matches the number of arguments of the function, which is not possible with ordinary lists and functions.
However, you can model this nicely using a discriminated union. You can define a partial function, which has either completed, or needs one more input:
type PartialFunction<'T, 'R> =
| Completed of 'R
| NeedsMore of ('T -> PartialFunction<'T, 'R>)
Your function f can now be written (with a slightly ugly syntax) as a PartialFunction<int, int> that keeps taking 5 inputs and then returns the result:
let f =
NeedsMore(fun a -> NeedsMore(fun b ->
NeedsMore(fun c -> NeedsMore(fun d ->
NeedsMore(fun e -> Completed(a+b+c+d+e))))))
Now you can implement applyPartially by deconstructing the list of arguments and applying them one by one to the partial function until you get the result:
let rec applyPartially f items =
match f, items with
| Completed r, _ -> r
| NeedsMore f, head::tail -> applyPartially (f head) tail
| NeedsMore _, _ -> failwith "Insufficient number of arguments"
The following now returns 15 as expected:
applyPartially f [1;2;3;4;5]
Disclaimer: Please don't use this. This is just plain evil.
let apply f v =
let args = v |> Seq.toArray
f.GetType().GetMethods()
|> Array.tryFind (fun m -> m.Name = "Invoke" && Array.length (m.GetParameters()) = Array.length args)
|> function None -> failwith "Not enough args" | Some(m) -> m.Invoke(f, args)
Just like you would expect:
let f a b c d e= a+b+c+d+e
apply f [1; 2; 3; 4; 5] //15
Related
Here is an example:
type Events =
| A of AData
| B of BData
| C of CData
and I have a list of those:
let events : Events list = ...
I need to build a list by event type. Right now I do this:
let listA =
events
|> List.map (fun x ->
match x with
| A a -> Some a
| _ -> None
)
|> List.choose id
and, repeat for each type...
I also thought I could do something like:
let rec split events a b c =
match events with
| [] -> (a |> List.rev, b |> List.rev, c |> List.rev)
| h :: t ->
let a, b, c =
match h with
| A x -> x::a, b, c
| B x -> a, x::b, c
| C x -> a, b, x::c
split t a b c
Is there a more elegant manner to solve this?
This processes a lot of data, so speed is important here.
You can fold back the list of events to avoid writing a recursive function and reversing results. With an anonymous record you will need to define it first and then pipe both arguments ||> to List.foldBack:
let eventsByType =
(events, {| listA = []; listB = []; listC = [] |})
||> List.foldBack (fun event state ->
match event with
| A a -> {| state with listA = a :: state.listA |}
| B b -> {| state with listB = b :: state.listB |}
| C c -> {| state with listC = c :: state.listC |})
With a named record it is more elegant:
{ listA = []; listB = []; listC = [] } |> List.foldBack addEvent events
addEvent is the same as the lambda above except usage of a named record {} instead of {||}.
I think your solution is pretty good, although you do pay a price for reversing the lists. The only other semi-elegant approach I can think of is to unzip a list of tuples:
let split events =
let a, b, c =
events
|> List.map (function
| A n -> Some n, None, None
| B s -> None, Some s, None
| C b -> None, None, Some b)
|> List.unzip3
let choose list = List.choose id list
choose a, choose b, choose c
This creates several intermediate lists, so careful internal use of Seq or Array instead might perform better. You would have to benchmark to be sure.
Test case:
split [
A 1
A 2
B "one"
B "two"
C true
C false
] |> printfn "%A" // [1; 2],[one; two],[true; false]
By the way, your current solution can be simplified to:
let listA =
events
|> List.choose (function A a -> Some a | _ -> None)
If you keep the union cases, you can group the list items like this.
let name = function
| A _ -> "A"
| B _ -> "B"
| C _ -> "C"
let lists =
events
|> List.groupBy name
|> dict
And then you can extract the data you want.
let listA = lists["A"] |> List.map (fun (A data) -> data)
(The compiler doesn't realize the list only consists of "A" cases, so it gives an incomplete pattern match warning😀)
I am trying to wrap my head around monads and how to use them in real world examples. The first "task" i set myself is to write an "Exception Monad" which of course (at this point) is nothing more than the "Either monad" twisted to suit my purpose.
My code looks like this:
type MException<'a> =
| Success of 'a
| Failure of string
with
static member returnM a =
Success a
static member bind f =
fun e ->
match e with
| Success a -> f a
| Failure m -> Failure m
static member map f =
fun e ->
match e with
| Success a -> Success (f a)
| Failure m -> Failure m
// Create a little test case to test my code
let divide (n, m) =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let round (f:float) =
Success ( System.Math.Round(f, 3) )
let toString (f:float) =
sprintf "%f" f
let divideRoundAndPrintNumber =
divide
>> MException<_>.bind round
>> MException<_>.map toString
// write the result
let result = divideRoundAndPrintNumber (11, 3)
match result with
| Success r -> printf "%s\n" r
| Failure m -> printf "%s\n" m
My question is the following: the divide function now takes a tuple. What can or should I do to make the bind and map functions behave correctly for functions with multiple parameters?
EDIT 30-12-2015:
Both the answers and comments of #Mark Seemann helped find the answer to the problem. #Mikhail provided the implementation of the solution. Currying is the right way of solving the problem. Computation Expressions are not a solution but a syntax abstraction which does work but gets complicated once you add async and other patterns to the problem. "Simple" composition seems like the easiest and "trueest" solution.
Change divideRoundAndPrintNumber to be a function instead of a value
let divide n m =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let divideRoundAndPrintNumber n =
divide n
>> MException<_>.bind round
>> MException<_>.map toString
Unfortunately I do not know enough about F# to understand your code completely. For example I do not understand the >> operator and the MException<_> expression. But I can give you an alternative solution for your problem. It utilzies a F# feature called "Computation Expressions". It enables you to do "Monadic" magic in a nice F#-like way:
type MException<'a> =
| Success of 'a
| Failure of string
type ExceptionBuilder() =
member this.Bind (m, f) =
match m with
| Success a -> f a
| Failure m -> Failure m
member this.Return (x) =
Success (x)
let ex = new ExceptionBuilder()
let divide n m =
if m = 0 then Failure "Cannot divide by zero"
else Success ((float n)/(float m))
let round (f : float) =
Success (System.Math.Round(f, 3))
let divideRoundAndPrintNumber a b =
ex {
let! c = divide a b
let! d = round c
printf "result of divideRoundAndPrintNumber: %f\n" d
return d
}
let result = divideRoundAndPrintNumber 11 0
match result with
| Success r -> printf "%f\n" r
| Failure m -> printf "%s\n" m
Apologies when my answer does not match your question completely but I hope it helps.
Here you can find an excellent blog post series about this topic:
http://fsharpforfunandprofit.com/posts/computation-expressions-intro/
I also found this article very enlightening:
http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
Monads have a fairly strict required structure, they must have:
Return: 'a -> m<'a>
and
Bind: m<'a> -> ('a -> m<'b>) -> m<'b>
Your divide function has the signature int*int -> MException<float>, i.e. it does indeed have the required 'a -> m<'b> form to be used with bind. When used with bind, it would act on something of type MException<int*int> and produce an MException<float>.
If divide is instead of type int -> int -> MException<float> (i.e. 'a -> 'b -> m<'c>'), we can't use it with bind directly. What we can do is unwrap the tuple and then supply the arguments one by one to create a lambda that does have the right form.
Let's add an extra Return so that we can see more clearly some different approaches for handling functions within these constraints:
let divideTupled (n, m) =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let divideRoundAndPrintNumber n m =
MException<_>.Return (n,m)
|> MException<_>.Bind divideTupled
|> MException<_>.Bind round
|> MException<_>.Map toString
or
let divideCurried n m =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
let divideRoundAndPrintNumber n m =
MException<_>.Return (n,m)
|> MException<_>.Bind (fun (n,m) -> divideCurried n m)
|> MException<_>.Bind round
|> MException<_>.Map toString
Computation expressions, as mentioned by Olaf, provide some nice syntactic sugar for working with monads in F#.
Why not define divide like you normally would?
let divide n m =
match m with
| 0 -> Failure "Cannot divide by zero"
| _ -> Success ((float n) / (float m))
You could then define divideRoundAndPrintNumber like this, likewise in curried form:
let divideRoundAndPrintNumber n m =
divide n m
|> MException<_>.bind round
|> MException<_>.map toString
FSI ad-hoc tests:
> let result = divideRoundAndPrintNumber 11 3;;
val result : MException<string> = Success "3.667000"
> let result = divideRoundAndPrintNumber 11 0;;
val result : MException<string> = Failure "Cannot divide by zero"
I want to write a tail recursive function to multiply all the values in a list by 2 in F#. I know there is a bunch of ways to do this but i want to know if this is even a viable method. This is purely for educational purposes. I realize that there is a built in function to do this for me.
let multiply m =
let rec innerfunct ax = function
| [] -> printfn "%A" m
| (car::cdr) -> (car <- car*2 innerfunct cdr);
innerfunct m;;
let mutable a = 1::3::4::[]
multiply a
I get two errors with this though i doubt they are the only problems.
This value is not mutable on my second matching condition
and
This expression is a function value, i.e. is missing arguments. Its type is 'a list -> unit. for when i call length a.
I am fairly new to F# and realize im probably not calling the function properly but i cant figure out why. This is mostly a learning experience for me so the explanation is more important than just fixing the code. The syntax is clearly off, but can i map *2 to a list just by doing the equivalent of
car = car*2 and then calling the inner function on the cdr of the list.
There are a number of issues that I can't easily explain without showing intermediate code, so I'll try to walk through a commented refactoring:
First, we'll go down the mutable path:
As F# lists are immutable and so are primitive ints, we need a way to mutate that thing inside the list:
let mutable a = [ref 1; ref 3; ref 4]
Getting rid of the superfluous ax and arranging the cases a bit, we can make use of these reference cells:
let multiply m =
let rec innerfunct = function
| [] -> printfn "%A" m
| car :: cdr ->
car := !car*2
innerfunct cdr
innerfunct m
We see, that multiply only calls its inner function, so we end up with the first solution:
let rec multiply m =
match m with
| [] -> printfn "%A" m
| car :: cdr ->
car := !car*2
multiply cdr
This is really only for it's own purpose. If you want mutability, use arrays and traditional for-loops.
Then, we go up the immutable path:
As we learnt in the mutable world, the first error is due to car not being mutable. It is just a primitive int out of an immutable list. Living in an immutable world means we can only create something new out of our input. What we want is to construct a new list, having car*2 as head and then the result of the recursive call to innerfunct. As usual, all branches of a function need to return some thing of the same type:
let multiply m =
let rec innerfunct = function
| [] ->
printfn "%A" m
[]
| car :: cdr ->
car*2 :: innerfunct cdr
innerfunct m
Knowing m is immutable, we can get rid of the printfn. If needed, we can put it outside of the function, anywhere we have access to the list. It will always print the same.
We finish by also making the reference to the list immutable and obtain a second (intermediate) solution:
let multiply m =
let rec innerfunct = function
| [] -> []
| car :: cdr -> car*2 :: innerfunct cdr
innerfunct m
let a = [1; 3; 4]
printfn "%A" a
let multiplied = multiply a
printfn "%A" multiplied
It might be nice to also multiply by different values (the function is called multiply after all and not double). Also, now that innerfunct is so small, we can make the names match the small scope (the smaller the scope, the shorter the names):
let multiply m xs =
let rec inner = function
| [] -> []
| x :: tail -> x*m :: inner tail
inner xs
Note that I put the factor first and the list last. This is similar to other List functions and allows to create pre-customized functions by using partial application:
let double = multiply 2
let doubled = double a
All that's left now is to make multiply tail-recursive:
let multiply m xs =
let rec inner acc = function
| [] -> acc
| x :: tail -> inner (x*m :: acc) tail
inner [] xs |> List.rev
So we end up having (for educational purposes) a hard-coded version of let multiply' m = List.map ((*) m)
F# is a 'single-pass' compiler, so you can expect any compilation error to have a cascading effect beneath the error. When you have a compilation error, focus on that single error. While you may have more errors in your code (you do), it may also be that subsequent errors are only consequences of the first error.
As the compiler says, car isn't mutable, so you can assign a value to it.
In Functional Programming, a map can easily be implemented as a recursive function:
// ('a -> 'b) -> 'a list -> 'b list
let rec map f = function
| [] -> []
| h::t -> f h :: map f t
This version, however, isn't tail-recursive, since it recursively calls map before it cons the head onto the tail.
You can normally refactor to a tail-recursive implementation by introducing an 'inner' implementation function that uses an accumulator for the result. Here's one way to do that:
// ('a -> 'b) -> 'a list -> 'b list
let map' f xs =
let rec mapImp f acc = function
| [] -> acc
| h::t -> mapImp f (acc # [f h]) t
mapImp f [] xs
Here, mapImp is the last operation to be invoked in the h::t case.
This implementation is a bit inefficient because it concatenates two lists (acc # [f h]) in each iteration. Depending on the size of the lists to map, it may be more efficient to cons the accumulator and then do a single reverse at the end:
// ('a -> 'b) -> 'a list -> 'b list
let map'' f xs =
let rec mapImp f acc = function
| [] -> acc
| h::t -> mapImp f (f h :: acc) t
mapImp f [] xs |> List.rev
In any case, however, the only reason to do all of this is for the exercise, because this function is already built-in.
In all cases, you can use map functions to multiply all elements in a list by two:
> let mdouble = List.map ((*) 2);;
val mdouble : (int list -> int list)
> mdouble [1..10];;
val it : int list = [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]
Normally, though, I wouldn't even care to define such function explicitly. Instead, you use it inline:
> List.map ((*) 2) [1..10];;
val it : int list = [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]
You can use all the above map function in the same way.
Symbols that you are creating in a match statement are not mutable, so when you are matching with (car::cdr) you cannot change their values.
Standard functional way would be to produce a new list with the computed values. For that you can write something like this:
let multiplyBy2 = List.map (fun x -> x * 2)
multiplyBy2 [1;2;3;4;5]
This is not tail recursive by itself (but List.map is).
If you really want to change values of the list, you could use an array instead. Then your function will not produce any new objects, just iterate through the array:
let multiplyArrayBy2 arr =
arr
|> Array.iteri (fun index value -> arr.[index] <- value * 2)
let someArray = [| 1; 2; 3; 4; 5 |]
multiplyArrayBy2 someArray
I'm trying to split an F# list into two by taking alternate elements. Here's my attempt:
let split l =
let rec loop l isEven result1 result2 =
match l with
| [] -> result1 result2
| [head::tail] when isEven -> loop tail (not isEven) head::result1 result2
| [head::tail] -> loop tail (not isEven) result1 head::result2
loop l false [] []
That gives me an error:
Program.fs(5,39): error FS0001: Type mismatch. Expecting a
'a
but given a
'b -> 'a list
The resulting type would be infinite when unifying ''a' and ''b -> 'a list'
I don't see how it can be infinite, and I don't understand why it thinks I'm giving it a function from 'b to 'a list. Could somebody tell me where I'm going wrong?
Jack did a good job of explaining what's wrong. Here's an alternate solution that matches two elements at a time. F#'s pattern matching documentation has a lot of great examples.
let split list =
let rec split odd even list =
match list with
| a::b::tail -> split (a::odd) (b::even) tail
| a::tail -> split (a::odd) even tail
| [] -> List.rev odd, List.rev even
split [] [] list
Example output.
printfn "%A" (split [1 .. 10])
System.Console.ReadLine() |> ignore
([1; 3; 5; 7; 9], [2; 4; 6; 8; 10])
Here's a fixed version:
let rec loop l isEven result1 result2 =
match l with
| [] ->
result1, result2
| head :: tail when isEven ->
loop tail (not isEven) (head :: result1) result2
| head :: tail ->
loop tail (not isEven) result1 (head :: result2)
In the first case ([]), I added a comma since the the loop function needs to return the values as a tuple. Without the comma, you're basically treating result1 like a function and applying result2 to it.
The empty list pattern was correct ([]) but in the other cases, you don't use the brackets -- just the cons (::) pattern.
You needed to enclose the head :: result in parenthesis, otherwise F# reads the code as if you wrote this: (loop tail (not isEven) head) :: (result1 result2).
Oh, and if you want the lists you're returning to be in the same order as the original list, you need to use List.rev when you return the lists, like this:
match l with
| [] ->
List.rev result1, List.rev result2
Finally, here's a slightly simplified version of your function -- you don't really need the isEven parameter to make the function work. Instead, you just try to keep the lists the same length:
let rec loop (result1, result2) l =
match l with
| [] ->
List.rev result1, List.rev result2
| hd :: tl ->
if List.length result1 = List.length result2 then
loop (hd :: result1, result2) tl
else
loop (result1, hd :: result2) tl
The simplest solution is not tail recursive but is very comprehensible:
let prepend2 (x, y) (xs, ys) = x::xs, y::ys
let rec split = function
| [] | [_] as xs -> xs, []
| x0::x1::xs -> prepend2 (x0, x1) (split xs)
I have two snippets of code that tries to convert a float list to a Vector3 or Vector2 list. The idea is to take 2/3 elements at a time from the list and combine them as a vector. The end result is a sequence of vectors.
let rec vec3Seq floatList =
seq {
match floatList with
| x::y::z::tail -> yield Vector3(x,y,z)
yield! vec3Seq tail
| [] -> ()
| _ -> failwith "float array not multiple of 3?"
}
let rec vec2Seq floatList =
seq {
match floatList with
| x::y::tail -> yield Vector2(x,y)
yield! vec2Seq tail
| [] -> ()
| _ -> failwith "float array not multiple of 2?"
}
The code looks very similiar and yet there seems to be no way to extract a common portion. Any ideas?
Here's one approach. I'm not sure how much simpler this really is, but it does abstract some of the repeated logic out.
let rec mkSeq (|P|_|) x =
seq {
match x with
| P(p,tail) ->
yield p
yield! mkSeq (|P|_|) tail
| [] -> ()
| _ -> failwith "List length mismatch" }
let vec3Seq =
mkSeq (function
| x::y::z::tail -> Some(Vector3(x,y,z), tail)
| _ -> None)
As Rex commented, if you want this only for two cases, then you probably won't have any problem if you leave the code as it is. However, if you want to extract a common pattern, then you can write a function that splits a list into sub-list of a specified length (2 or 3 or any other number). Once you do that, you'll only use map to turn each list of the specified length into Vector.
The function for splitting list isn't available in the F# library (as far as I can tell), so you'll have to implement it yourself. It can be done roughly like this:
let divideList n list =
// 'acc' - accumulates the resulting sub-lists (reversed order)
// 'tmp' - stores values of the current sub-list (reversed order)
// 'c' - the length of 'tmp' so far
// 'list' - the remaining elements to process
let rec divideListAux acc tmp c list =
match list with
| x::xs when c = n - 1 ->
// we're adding last element to 'tmp',
// so we reverse it and add it to accumulator
divideListAux ((List.rev (x::tmp))::acc) [] 0 xs
| x::xs ->
// add one more value to 'tmp'
divideListAux acc (x::tmp) (c+1) xs
| [] when c = 0 -> List.rev acc // no more elements and empty 'tmp'
| _ -> failwithf "not multiple of %d" n // non-empty 'tmp'
divideListAux [] [] 0 list
Now, you can use this function to implement your two conversions like this:
seq { for [x; y] in floatList |> divideList 2 -> Vector2(x,y) }
seq { for [x; y; z] in floatList |> divideList 3 -> Vector3(x,y,z) }
This will give a warning, because we're using an incomplete pattern that expects that the returned lists will be of length 2 or 3 respectively, but that's correct expectation, so the code will work fine. I'm also using a brief version of sequence expression the -> does the same thing as do yield, but it can be used only in simple cases like this one.
This is simular to kvb's solution but doesn't use a partial active pattern.
let rec listToSeq convert (list:list<_>) =
seq {
if not(List.isEmpty list) then
let list, vec = convert list
yield vec
yield! listToSeq convert list
}
let vec2Seq = listToSeq (function
| x::y::tail -> tail, Vector2(x,y)
| _ -> failwith "float array not multiple of 2?")
let vec3Seq = listToSeq (function
| x::y::z::tail -> tail, Vector3(x,y,z)
| _ -> failwith "float array not multiple of 3?")
Honestly, what you have is pretty much as good as it can get, although you might be able to make a little more compact using this:
// take 3 [1 .. 5] returns ([1; 2; 3], [4; 5])
let rec take count l =
match count, l with
| 0, xs -> [], xs
| n, x::xs -> let res, xs' = take (count - 1) xs in x::res, xs'
| n, [] -> failwith "Index out of range"
// split 3 [1 .. 6] returns [[1;2;3]; [4;5;6]]
let rec split count l =
seq { match take count l with
| xs, ys -> yield xs; if ys <> [] then yield! split count ys }
let vec3Seq l = split 3 l |> Seq.map (fun [x;y;z] -> Vector3(x, y, z))
let vec2Seq l = split 2 l |> Seq.map (fun [x;y] -> Vector2(x, y))
Now the process of breaking up your lists is moved into its own generic "take" and "split" functions, its much easier to map it to your desired type.