formatting Composite function in f# - f#

I have a recursive function in f# that iterates a string[] of commands that need to be run, each command runs a new command to generate a map to be passed to the next function.
The commands run correctly but are large and cumbersome to read, I believe that there is a better way to order / format these composite functions using pipe syntax however coming from c# as a lot of us do i for the life of me cannot seem to get it to work.
my command is :
let rec iterateCommands (map:Map<int,string array>) commandPosition =
if commandPosition < commands.Length then
match splitCommand(commands.[0]).[0] with
|"comOne" ->
iterateCommands (map.Add(commandPosition,create(splitCommand commands.[commandPosition])))(commandPosition+1)
The closest i have managed is by indenting the function but this is messy :
iterateCommands
(map.Add
(commandPosition,create
(splitCommand commands.[commandPosition])
)
)
(commandPosition+1)
Is it even possible to reformat this in f#? From what i have read i believe it possible, any help would be greatly appreciated
The command/variable types are:
commandPosition - int
commands - string[]
splitCommand string -> string[]
create string[] -> string[]
map : Map<int,string[]>
and of course the map.add map -> map + x

It's often hard to make out what is going on in a big statement with multiple inputs. I'd give names to the individual expressions, so that a reader can jump into any position and have a rough idea what's in the values used in a calculation, e.g.
let inCommands = splitCommand commands.[commandPosition]
let map' = map.Add (commandPosition, inCommands)
iterateCommands map' inCommands
Since I don't know what is being done here, the names aren't very meaningful. Ideally, they'd help to understand the individual steps of the calculation.

It'd be a bit easier to compose the call if you changed the arguments around:
let rec iterateCommands commandPosition (map:Map<int,string array>) =
// ...
That would enable you to write something like:
splitCommand commands.[commandPosition]
|> create
|> (fun x -> commandPosition, x)
|> map.Add
|> iterateCommands (commandPosition + 1)
The fact that commandPosition appears thrice in the composition is, in my opinion, a design smell, as is the fact that the type of this entire expression is unit. It doesn't look particularly functional, but since I don't understand exactly what this function attempts to do, I can't suggest a better design.
If you don't control iterateCommands, and hence can't change the order of arguments, you can always define a standard functional programming utility function:
let flip f x y = f y x
This enables you to write the following against the original version of iterateCommands:
splitCommand commands.[commandPosition]
|> create
|> (fun x -> commandPosition, x)
|> map.Add
|> (flip iterateCommands) (commandPosition + 1)

Related

SUMPRODUCT in F# without variables

I have already done some searches, and this question is a duplicate of another post. I am posting this just for future reference.
Is it possible to define SUMPRODUCT without explicitly using variable names x, y?
Original Function:
let SUMPRODUCT x y = List.map2 (*) x y |> List.sum
SUMPRODUCT [1;4] [3;25] // Result: 103
I was hoping to do this:
// CONTAINS ERROR!
let SUMPRODUCT = (List.map2 (*)) >> List.sum
// CONTAINS ERROR!
But F# comes back with an error.
I have already found the solution on another post, but if you have any suggestions please let me know. Thank you.
Function composition only works when the input function takes a single argument. However, in your example, the result of List.map2 (*) is a function that takes two separate arguments and so it cannot be easily composed with List.sum using >>.
There are various ways to work around this if you really want, but I would not do that. I think >> is nice in a few rare cases where it fits nicely, but trying to over-use it leads to unreadable mess.
In some functional languages, the core library defines helpers for turning function with two arguments into a function that takes a tuple and vice versa.
let uncurry f (x, y) = f x y
let curry f x y = f (x, y)
You could use those two to define your sumProduct like this:
let sumProduct = curry ((uncurry (List.map2 (*))) >> List.sum)
Now it is point-free and understanding it is a fun mental challenge, but for all practical purposes, nobody will be able to understand the code and it is also longer than your original explicit version:
let sumProduct x y = List.map2 (*) x y |> List.sum
According to this post:
What am I missing: is function composition with multiple arguments possible?
Sometimes "pointed" style code is better than "pointfree" style code, and there is no good way to unify the type difference of the original function to what I hope to achieve.

F# and lisp-like apply function

For starters, I'm a novice in functional programming and F#, therefore I don't know if it's possible to do such thing at all. So let's say we have this function:
let sum x y z = x + y + z
And for some reason, we want to invoke it using the elements from a list as an arguments. My first attempt was just to do it like this:
//Seq.fold (fun f arg -> f arg) sum [1;2;3]
let rec apply f args =
match args with
| h::hs -> apply (f h) hs
| [] -> f
...which doesn't compile. It seems impossible to determine type of the f with a static type system. There's identical question for Haskell and the only solution uses Data.Dynamic to outfox the type system. I think the closest analog to it in F# is Dynamitey, but I'm not sure if it fits. This code
let dynsum = Dynamitey.Dynamic.Curry(sum, System.Nullable<int>(3))
produces dynsum variable of type obj, and objects of this type cannot be invoked, furthermore sum is not a .NET Delegate.So the question is, how can this be done with/without that library in F#?
F# is a statically typed functional language and so the programming patterns that you use with F# are quite different than those that you'd use in LISP (and actually, they are also different from those you'd use in Haskell). So, working with functions in the way you suggested is not something that you'd do in normal F# programming.
If you had some scenario in mind for this function, then perhaps try asking about the original problem and someone will help you find an idiomatic F# approach!
That said, even though this is not recommended, you can implement the apply function using the powerful .NET reflection capabilities. This is slow and unsafe, but if is occasionally useful.
open Microsoft.FSharp.Reflection
let rec apply (f:obj) (args:obj list) =
let invokeFunc =
f.GetType().GetMethods()
|> Seq.find (fun m ->
m.Name = "Invoke" &&
m.GetParameters().Length = args.Length)
invokeFunc.Invoke(f, Array.ofSeq args)
The code looks at the runtime type of the function, finds Invoke method and calls it.
let sum x y z = x + y + z
let res = apply sum [1;2;3]
let resNum = int res
At the end, you need to convert the result to an int because this is not statically known.

Can I use different workflows simultaneously in F#?

I need my state to be passed along while being able to chain functions with the maybe workflow. Is there a way for 2 workflows to share the same context? If no, what is the way of doing it?
UPDATE:
Well, I have a state that represents a segment of available ID's for the entities that I am going to create in the database. So once an ID is acquired the state has to be transformed to a newer state with the next available ID and thrown away so that nobody can use it again. I don't want to mutate the state for the sake of being idiomatic. The State monad looks like a way to go as it hides the transformation and passes the state along. Once the state workflow is in place I cannot use the Maybe workflow which is something I use everywhere.
As stated in the previous answer, one way to combine workflows in F# (Monads in Haskell) is by using a technique called Monad Transformers.
In F# this is really tricky, here is a project that deals with that technique.
It's possible to write the example of the previous answer by automatically combining State and Maybe (option), using that library:
#r #"c:\packages\FSharpPlus-1.0.0\lib\net45\FSharpPlus.dll"
open FSharpPlus
open FSharpPlus.Data
// Stateful computation
let computation =
monad {
let! x = get
let! y = OptionT (result (Some 10))
do! put (x + y)
let! x = get
return x
}
printfn "Result: %A" (State.eval (OptionT.run computation) 1)
So this is the other alternative, instead of creating your custom workflow, use a generic workflow that will be automatically inferred (a-la Haskell).
In F# you cannot easily mix different types of computation expressions as you would do in Haskell by using Monad Transformers or similar techniques. You could however build your own Monad, embedding state threading and optional values, as in:
type StateMaybe<'T> =
MyState -> option<'T> * MyState
// Runs the computation given an initial value and ignores the state result.
let evalState (sm: StateMaybe<'T>) = sm >> fst
// Computation expression for SateMaybe monad.
type StateMaybeBuilder() =
member this.Return<'T> (x: 'T) : StateMaybe<'T> = fun s -> (Some x, s)
member this.Bind(sm: StateMaybe<'T>, f: 'T -> StateMaybe<'S>) = fun s ->
let mx,s' = sm s
match mx with
| Some x -> f x s'
| None -> (None, s)
// Computation expression builder.
let maybeState = new StateMaybeBuilder()
// Lifts an optional value to a StateMaybe.
let liftOption<'T> (x: Option<'T>) : StateMaybe<'T> = fun s -> (x,s)
// Gets the current state.
let get : StateMaybe<MyState> = fun s -> (Some s,s)
// Puts a new state.
let put (x: MyState) : StateMaybe<unit> = fun _ -> (Some (), x)
Here's an example computation:
// Stateful computation
let computation =
maybeState {
let! x = get
let! y = liftOption (Some 10)
do! put (x + y)
let! x = get
return x
}
printfn "Result: %A" (evalState computation 1)
StateMaybe may be generalized further by making the type of the state component generic.
Others already gave you a direct answer to your question. However, I think that the way the question is stated leads to a solution that is not very idiomatic from the F# perspective - this might work for you as long as you are the only person working on the code, but I would recommend against doing that.
Even with the added details, the question is still fairly general, but here are two suggestions:
There is nothing wrong with reasonably used mutable state in F#. For example, it is perfectly fine to create a function that generates IDs and pass it along:
let createGenerator() =
let currentID = ref 0
(fun () -> incr currentID; !currentID)
Do you really need to generate the IDs while you are building the entities? It sounds like you could just generate a list of entities without ID and then use Seq.zip to zip the final list of entities with list of IDs.
As for the maybe computation, are you using it to handle regular, valid states, or to handle exceptional states? (It sounds like the first, which is the right way of doing things - but if you need to handle truly exceptional states, then you might want to use ordinary .NET exceptions).

Using functions before they are declared

For the sake of using literate programming (i.e. cweb) in F#, I need to be able to forward declare functions (i.e. use them before defining them). I came up with two ways, both of them unpleasing. Can you think of something better (easier to use for the programmer)?
Nice, but doesn't work with polymorphic functions
// This can be ugly
let declare<'a> = ref Unchecked.defaultof<'a>
// This has to be beautiful
let add = declare<float -> float>
let ``function I want to explain that depends on add`` nums = nums |> Seq.map !add
add := fun x -> x + 1.
Ugly, but works with everything
// This can be ugly
type Literate() =
static member Declare<'a, 'b> (ref : obj ref) (x : 'a) : 'b =
unbox <| (unbox<obj -> obj> !ref)
static member Define<'a, 'b> (func : 'a -> 'b) (ref : obj ref) (f : 'a -> 'b) =
ref := box (unbox<'a> >> f >> box)
// This has to be beautiful
let rec id (x : 'a) : 'a = Literate.Declare idImpl x
and idImpl = ref null
let f () = id 100 + id 200
Literate.Define id idImpl (fun x -> x)
I used a tool that follows the same ideas as literate programming when creating www.tryjoinads.org. A document is simply a Markdown with code snippets that get turned into an F# source code that you can run and the snippets have to be in a correct order. (In some literate programming tools, the documentation is written in commments, but the idea is the same.)
Now, I think that making your code more complicated so that you can write it in a literate programming style (and document it) is introducing a lot of accidental complexity and it is defeating the main purpose of literate programming.
So, if I wanted to solve this problem, I would extend my literate programming tool with some annotation that specifies the order of code blocks that is needed to make the script work (and a simple pre-processing tool can re-order them when generating F# input). You can take a [look at my build script][1] for TryJoinads, which would be fairly easy to extend to do this.
The tool I used for TryJoinads already provides some meta-tags that can be used to hide code blocks from the output, so you can write something like:
## This is my page heading
[hide]
// This function will be hidden from the generated HTML
// but it is visible to the F# compiler
let add a b = a + b
Here is the description for the other function:
let functionThatUsesAdd x = add x x
And later on I can repeat `add` with more comments (and I can add an annotation
`module` to avoid conflicts with the previous declaration):
[module=Demo]
let add a b =
// Add a and b
a + b
This also isn't perfect, because you have to duplicate functions, but at least your generated blog post or HTML documentation will not be obscured by things that do not matter. But of course, adding some meta-command like module or hide to specify order of blocks wouldn't be too hard and it would be a clean solution.
In summary, I think you just need a better literate programming tool, not different F# code or F# langauge.
Perhaps I'm missing something, but why aren't you going all the way and 'doing it properly'?
Using the function first:
<<test.fs>>=
<<add>>
let inc = add 1
Declaring the function afterwards:
<<add>>=
let add a b = a + b
Since functions are first-class objects in F#, you can pass them around instead -- which presents a much nicer (and still immutable) solution than forward references.
let dependentFunction f nums = nums |> Seq.map f
let ``function I want to explain that depends on add`` nums =
dependentFunction (fun x -> x + 1.) nums
Also, in most cases you should be able to use currying (partial function application) to simplify the code further but the type inference for seq<'T> is a little strange in F# because it's usually used as a flexible type (similar to covariance in C# 4.0). To illustrate:
// This doesn't work because of type inference on seq<'T>,
// but it should work with most other types.
let ``function I want to explain that depends on add`` =
dependentFunction (fun x -> x + 1.)
Finally, a good rule of thumb for using ref or mutable in F# is that if you're only going to assign the value once (to initialize it), there's probably a cleaner, more functional way to write that code (passing the value as a function parameter (as above) and lazy are two such approaches). Obviously there are exceptions to this rule, but even then they should be used very sparingly.
As I said, this is wrong (and you should publish a blog article, or a FPish post, about why you're doing this)), but here is my take:
let ``function I want to explain that depends on add``
(add : float -> float) = nums |> Seq.map add
let add = (+) 1.
let ``function I want to explain that depends on add`` = ``function I want to explain that depends on add`` add

F# currying efficiency?

I have a function that looks as follows:
let isInSet setElems normalize p =
normalize p |> (Set.ofList setElems).Contains
This function can be used to quickly check whether an element is semantically part of some set; for example, to check if a file path belongs to an html file:
let getLowerExtension p = (Path.GetExtension p).ToLowerInvariant()
let isHtmlPath = isInSet [".htm"; ".html"; ".xhtml"] getLowerExtension
However, when I use a function such as the above, performance is poor since evaluation of the function body as written in "isInSet" seems to be delayed until all parameters are known - in particular, invariant bits such as (Set.ofList setElems).Contains are reevaluated each execution of isHtmlPath.
How can best I maintain F#'s succint, readable nature while still getting the more efficient behavior in which the set construction is preevaluated.
The above is just an example; I'm looking for a general approach that avoids bogging me down in implementation details - where possible I'd like to avoid being distracted by details such as the implementation's execution order since that's usually not important to me and kind of undermines a major selling point of functional programming.
As long as F# doesn't differentiate between pure and impure code, I doubt we'll see optimisations of that kind. You can, however, make the currying explicit.
let isInSet setElems =
let set = Set.ofList setElems
fun normalize p -> normalize p |> set.Contains
isHtmlSet will now call isInSet only once to obtain the closure, at the same time executing ofList.
The answer from Kha shows how to optimize the code manually by using closures directly. If this is a frequent pattern that you need to use often, it is also possible to define a higher-order function that constructs the efficient code from two functions - the first one that does pre-processing of some arguments and a second one which does the actual processing once it gets the remaining arguments.
The code would look like this:
let preProcess finit frun preInput =
let preRes = finit preInput
fun input -> frun preRes input
let f : string list -> ((string -> string) * string) -> bool =
preProcess
Set.ofList // Pre-processing of the first argument
(fun elemsSet (normalize, p) -> // Implements the actual work to be
normalize p |> elemsSet.Contains) // .. done once we get the last argument
It is a question whether this is more elegant though...
Another (crazy) idea is that you could use computation expressions for this. The definition of computation builder that allows you to do this is very non-standard (it is not something that people usually do with them and it isn't in any way related to monads or any other theory). However, it should be possible to write this:
type CurryBuilder() =
member x.Bind((), f:'a -> 'b) = f
member x.Return(a) = a
let curry = new CurryBuilder()
In the curry computation, you can use let! to denote that you want to take the next argument of the function (after evaluating the preceeding code):
let f : string list -> (string -> string) -> string -> bool = curry {
let! elems = ()
let elemsSet = Set.ofList elems
printf "elements converted"
let! normalize = ()
let! p = ()
printf "calling"
return normalize p |> elemsSet.Contains }
let ff = f [ "a"; "b"; "c" ] (fun s -> s.ToLower())
// Prints 'elements converted' here
ff "C"
ff "D"
// Prints 'calling' two times
Here are some resources with more information about computation expressions:
The usual way of using computation expressions is described in free sample chapter of my book: Chapter 12: Sequence Expressions and Alternative Workflows (PDF)
The example above uses some specifics of the translation which is in full detailes described in the F# specification (PDF)
#Kha's answer is spot on. F# cannot rewrite
// effects of g only after both x and y are passed
let f x y =
let xStuff = g x
h xStuff y
into
// effects of g once after x passed, returning new closure waiting on y
let f x =
let xStuff = g x
fun y -> h xStuff y
unless it knows that g has no effects, and in the .NET Framework today, it's usually impossible to reason about the effects of 99% of all expressions. Which means the programmer is still responsible for explicitly coding evaluation order as above.
Currying does not hurt. Currying sometimes introduces closures as well. They are usually efficient too.
refer to this question I asked before. You can use inline to boost performance if necessary.
However, your performance problem in the example is mainly due to your code:
normalize p |> (Set.ofList setElems).Contains
here you need to perform Set.ofList setElems even you curry it. It costs O(n log n) time.
You need to change the type of setElems to F# Set, not List now. Btw, for small set, using lists is faster than sets even for querying.

Resources