So I'm working with HttpRuntime.cache which returns an IDictionaryEnumerator as its' enumerator, which does not seem to be compatible with List or Seq, so the only way I can find to use it is to drop down into unholy imperative code like so:
member this.GetCountStartsWith keyPrefix =
let enumerator = HttpRuntime.Cache.GetEnumerator()
let mutable counter = 0
while enumerator.MoveNext() do
match enumerator.Key.ToString().StartsWith(keyPrefix) with
| true -> counter <- counter + 1
| false -> ()
counter
I had the thought that I could make a helper function to dump this into a List, but there could be many thousands of elements potentially so that would be a bad idea performance wise. Any way to work with this thing in a more idiomatic way?
The problem is that you have an IEnumerator, which isn't generic. However, there's two helper methods to solve that: OfType and Cast.
In practice, you want to do something like:
let enumerable = HttpRuntime.Cache |> Seq.cast<DictionaryEntry>
Now enumerable is a proper generic enumerable :)
Related
In F# I need to get a list from an existing list with the value at a particular index changed from the original. All I can find on google and here relates to changing something based on value rather than index (fair enough, because lists don't really have a concept of "index", but I bet everyone knew what I meant).
This is obviously easy enough to code. At the moment I have:
// Replace element at index with newElement in seq. Does nothing if index is outside seq.
let updateElement index newElement seq =
let rec updateElementHelper seq count result =
match seq with
| [] -> result |> List.rev
| head::tail ->
if count = index then
updateElementHelper [] (count + 1) (newElement::result)#tail
else
updateElementHelper tail (count + 1) (head::result)
updateElementHelper seq 0 []
which seems to work just fine, but is there a more native way than this?
(F# newbie - or rather, returing after a very long break and never having got all that far the first time around).
The easiest way to implement this is probably to use the List.mapi function - it calls a function you provide for each element of the list and gives you an index, so you can either return the original element or your new element, depending on the index:
let updateElement index element list =
list |> List.mapi (fun i v -> if i = index then element else v)
updateElement 4 40 [ 0 .. 9 ]
As noted by #Jarak, if you need to do this often, then it might be worth thinking whether there is some other more functional approach to your problem where you do not rely on indices - doing something like this would not be very typical thing to do in functional code.
I am assuming that you don't want to allow the list to be mutable. If you did, then you could just index into the list and update the value, e.g. mylist.[index] <- newValue.
I will say right now that any operation on a list that uses any other sort of access than the typical "head + tail -> recurse on tail" style is a strong sign that a list isn't the right data structure for your operation. See e.g. Juliet's answer here. Typically, if you want to be operating on a linear data structure by index, an array is your best bet.
The easiest way I can think of to do this if you still want to do it with a list, would be something like the following:
let newList = oldList.[..index - 1] # (newValue :: oldList.[index + 1..])
(I might possibly have the indices slightly off)
This will probably have very poor performance, however. I think it would be reasonably fair to say that many F#-ers would call any use of # or List slicing a code smell. As a very infrequent operation on small lists it might be alright, but if it will be used frequently, or on large lists, then it would be a good time to start thinking if a list is really the right collection data structure for your task.
getting an error when I try to run this line of code and I can't figure out why
let validCol column value : bool =
for i in 0..8 do
if sudokuBoard.[i,column] = value then
false
else true
As Tyler Hartwig says a for loop cannot return a value except unit.
On the other hand, inside a list comprehension or a seq Computation Expression you can use for to yield the values and then test if the one you are looking for exists:
let validCol column value : bool =
seq { for i in 0..8 do yield sudokuBoard.[i,column] }
|> Seq.exists value
|> not
In F#, the last call made is what is returned, you have explicitly declared you are returning a bool.
The for loop is unable to return or aggregate multiple values, bun instead, returns unit.
let validCol column value : bool =
for i in 0..8 do
if sudokuBoard.[i,column] = value then
false
else
true
Here, you'll need to figure out how to aggregate all the bool to get your final result. I'm not quite sure what this is supposed to return, or I'd give an example.
It looks like you are looking for a short-cut out of the loop like in C# you can use continue, break or return to exit a loop.
In F# the way to accomplish that with performance is to use tail-recursion. You could achieve it with while loops but that requires mutable variables which tail-recursion doesn't need (although we sometimes uses it).
A tail-recursive function is one that calls itself at the very end and doesn't look at the result:
So this is tail-recursive
let rec loop acc i = if i > 0 then loop (acc + i) (i - 1) else acc
Where this isn't
let rec loop fib i = if i < 1 then 1 else fib (i - 1) + fib (i - 2)
If F# compiler determines a function is tail-recursive the compiler applies tail-recursion optimization (TCO) on the function, basically it unrolls it into an efficient for loop that looks a lot like the loop would like in C#.
So here is one way to write validCol using tail-recursion:
let validCol column value : bool =
// loops is tail-recursive
let rec loop column value i =
if i < 9 then
if sudokuBoard.[i,column] = value then
false // The value already exists in the column, not valid
else
loop column value (i + 1) // Check next row.
else
true // Reach the end, the value is valid
loop column value 0
Unfortunately; F# compiler doesn't have an attribute to force TCO (like Scala or kotlin does) and therefore if you make a slight mistake you might end up with a function that isn't TCO. I think I saw GitHub issue about adding such an attribute.
PS. seq comprehensions are nice in many cases but for a sudoku solver I assume you are looking for something that is as fast as possible. seq comprehensions (and LINQ) I think adds too much overhead for a sudoku solver whereas tail-recursion is about as quick as you can get in F#.
PS. In .NET 2D arrays are slower than 1D arrays, just FYI. Unsure if it has improved with dotnet core.
I think that's a well-known limitation of F# but I couldn't find any good workarounds…
So, here is the code (I tried to make it as simple as possible, so probably it looks like it doesn't make any sense):
[<ReflectedDefinition>]
type Human (makeAName: unit -> string) as self =
let mutable cats : Cat array = [| |]
do
// get a cat
cats <- Array.append cats [| new Cat (self, makeAName ()) |]
member this.Cats = cats
and
[<ReflectedDefinition>]
Cat (owner : Human, name : string) = class end
The compiler says:
error FS0452: Quotations cannot contain inline assembly code or pattern matching on arrays
Actually it is the combination of as self and array property getter that breaks everything.
The points here are:
I really want to use arrays, because I want WebSharper to translate my collections to JavaSript arrays.
I really need a self-identifier in constructors.
I really need classes (i.e. functional style won't work).
Per-method self-identifiers (member this.Foo) work fine.
One workaround I can think of is making constructors private and using static methods to construct objects. This way I don't need as self. But it is just silly.
Are there any better options?
Update:
Here is an even simpler example:
[<ReflectedDefinition>]
type User (uid: int) as self =
let ROOT_UID = 0
member this.isRoot = (uid = ROOT_UID)
With as self I can't even define a class constant. Well, it's actually a separate question, but I'll ask it here: how do I define a class constant in this particular case?
I do not think it is silly at all. We actually prefer static constructor methods for clarity, even in code that does not use WebSharper. In the whole IntelliFactory codebase we rarely, if ever use self.
You are hitting two annoying limitations of F# compiler and quotations. As you point out, static methods can solve the self problem:
[<ReflectedDefinition>]
type Human private (cats: ref<Cat []>) =
member this.Cats = !cats
static member Create(makeAName: unit -> string) =
let cats = ref [| |]
let h = Human(cats)
let cat = Cat(h, makeAName())
cats := [| cat |]
h
and [<ReflectedDefinition>] Cat (owner: Human, name: string) =
class
end
There are many other ways to accomplish this, for example you can get rid of ref indirection.
Second, you often get FS0452 in ReflectedDefinition code with array operations, even in plain static methods. This usually can be resolved by using library functions instead of direct array access (Array.iter, Array.map).
For the second example, you really want this:
[<ReflectedDefinition>]
module Users =
[<Literal>]
let ROOT_UID = 0
type User(uid: int) =
member this.isRoot = (uid = ROOT_UID)
The [<Literal>] annotation will let you pattern-match on your constants, which can be handy if there is more than one.
For your points:
I really want to use arrays - that should be OK
I really need a self-identifier - it is never necessary, just as constructors are not
I really need classes (i.e. functional style won't work) - definitely not true
Per-method self-identifiers (member this.Foo) work fine - yes, and are useful
I thought that I might be able to do this with quotations - but I can't see how.
Should I just use a table of the functions with their names - or is their a way of doing this?
Thanks.
For more info......
I'm calling a lot of f# functions from excel and I wondered if I could write a f# function
let fs_wrapper (f_name:string) (f_params:list double) =
this bit calls fname with f_params
and then use
=fs_wrapper("my_func", 3.14, 2.71)
in the sheet rather than wrap all the functions separately.
You'll need to use standard .NET Reflection to do this. Quotations aren't going to help, because they represent function calls using standard .NET MethodInfo, so you'll need to use reflection anyway. The only benefit of quotations (compared to naive reflection) is that you can compile them, which could give you better performance (but the compilation isn't perfect).
Depending on your specific scenario (e.g. where are the functions located), you'd have to do something like:
module Functions =
let sin x = sin(x)
let sqrt y = sqrt(y)
open System.Reflection
let moduleInfo =
Assembly.GetExecutingAssembly().GetTypes()
|> Seq.find (fun t -> t.Name = "Functions")
let name = "sin"
moduleInfo.GetMethod(name).Invoke(null, [| box 3.1415 |])
Unless you need some extensibility or have a large number of functions, using a dictionary containing string as a key and function value as the value may be an easier option:
let funcs =
dict [ "sin", Functions.sin;
"sqrt", Functions.sqrt ]
funcs.[name](3.1415)
There are many methods but one way is to use Reflection, for instance:
typeof<int>.GetMethod("ToString", System.Type.EmptyTypes).Invoke(1, null)
typeof<int>.GetMethod("Parse", [|typeof<string>|]).Invoke(null, [|"112"|])
GetMethod optionally takes an array of types that define the signature, but you can skip that if your method is unambiguous.
Following up on what Thomas alluded to, have a look at Using and Abusing the F# Dynamic Lookup Operator by Matthew Podwysocki. It offers a syntactically clean way for doing dynamic lookup in F#.
This is a pretty simple question, and I just wanted to check that what I'm doing and how I'm interpreting the F# makes sense. If I have the statement
let printRandom =
x = MyApplication.getRandom()
printfn "%d" x
x
Instead of creating printRandom as a function, F# runs it once and then assigns it a value. So, now, when I call printRandom, instead of getting a new random value and printing it, I simply get whatever was returned the first time. I can get around this my defining it as such:
let printRandom() =
x = MyApplication.getRandom()
printfn "%d" x
x
Is this the proper way to draw this distinction between parameter-less functions and values? This seems less than ideal to me. Does it have consequences in currying, composition, etc?
The right way to look at this is that F# has no such thing as parameter-less functions. All functions have to take a parameter, but sometimes you don't care what it is, so you use () (the singleton value of type unit). You could also make a function like this:
let printRandom unused =
x = MyApplication.getRandom()
printfn "%d" x
x
or this:
let printRandom _ =
x = MyApplication.getRandom()
printfn "%d" x
x
But () is the default way to express that you don't use the parameter. It expresses that fact to the caller, because the type is unit -> int not 'a -> int; as well as to the reader, because the call site is printRandom () not printRandom "unused".
Currying and composition do in fact rely on the fact that all functions take one parameter and return one value.
The most common way to write calls with unit, by the way, is with a space, especially in the non .NET relatives of F# like Caml, SML and Haskell. That's because () is a singleton value, not a syntactic thing like it is in C#.
Your analysis is correct.
The first instance defines a value and not a function. I admit this caught me a few times when I started with F# as well. Coming from C# it seems very natural that an assignment expression which contains multiple statements must be a lambda and hence delay evaluated.
This is just not the case in F#. Statements can be almost arbitrarily nested (and it rocks for having locally scoped functions and values). Once you get comfortable with this you start to see it as an advantage as you can create functions and continuations which are inaccessible to the rest of the function.
The second approach is the standard way for creating a function which logically takes no arguments. I don't know the precise terminology the F# team would use for this declaration though (perhaps a function taking a single argument of type unit). So I can't really comment on how it would affect currying.
Is this the proper way to draw this
distinction between parameter-less
functions and values? This seems less
than ideal to me. Does it have
consequences in currying, composition,
etc?
Yes, what you describe is correct.
For what its worth, it has a very interesting consequence able to partially evaluate functions on declaration. Compare these two functions:
// val contains : string -> bool
let contains =
let people = set ["Juliet"; "Joe"; "Bob"; "Jack"]
fun person -> people.Contains(person)
// val contains2 : string -> bool
let contains2 person =
let people = set ["Juliet"; "Joe"; "Bob"; "Jack"]
people.Contains(person)
Both functions produce identical results, contains creates its people set on declaration and reuses it, whereas contains2 creates its people set everytime you call the function. End result: contains is slightly faster. So knowing the distinction here can help you write faster code.
Assignment bodies looking like function bodies have cought a few programmers unaware. You can make things even more interesting by having the assignment return a function:
let foo =
printfn "This runs at startup"
(fun () -> printfn "This runs every time you call foo ()")
I just wrote a blog post about it at http://blog.wezeku.com/2010/08/23/values-functions-and-a-bit-of-both/.