So I have this sample piece of code, and I want to add a try-with block inside it:
static member private SomeFunc
(someParam: list<DateTime*int>) =
let someLocalVar = helpers.someOtherFunc someParam
let theImportantLocalVar =
List.fold
helpers.someFoldFunc
([],someLocalVar.First())
someLocalVar.Tail
let first = fst theImportantLocalVar
let tail = someParam.Tail
helpers.someLastFunc(first,tail,theImportantLocalVar)
The try-with block I want to add should just wrap the call to List.fold, however if I do wrap only that line, then I cannot access the variable theImportantLocalVar later.
For now, as a workaround, I have put the try-with block wrapping the whole function body (except the first line about assigning someLocalVar), but I would like to avoid this:
static member private SomeFunc
(someParam: list<DateTime*int>) =
let someLocalVar = helpers.someOtherFunc someParam
try
let theImportantLocalVar =
List.fold
helpers.someFoldFunc
([],someLocalVar.First())
someLocalVar.Tail
let first = fst theImportantLocalVar
let tail = someParam.Tail
helpers.someLastFunc(first,tail,theImportantLocalVar)
with
| BadData(_) -> raise (new
ArgumentException("output values can only increase: " + someLocalVar,
"someParam"))
In C#, I would have solved it with a bool exception=false that I would turn into true inside the catch block (to later query it in the second part of the function), or initializing theImportantLocalVar with null to compare it later; however, in F# for this I would need the mutable keyword, something that is discouraged.
So how to do this without using a mutable variable?
try/with is an expression, so you can do this:
let theImportantLocalVar =
try
List.fold
helpers.someFoldFunc
([],someLocalVar.First())
someLocalVar.Tail
with
| BadData(_) -> raise (new
ArgumentException("output values can only increase: " + someLocalVar,
"someParam"))
Related
take
let memoization f =
// The dictionary is used to store values for every parameter that has been seen
let cache = Dictionary<_,_>()
fun c ->
let exist, value = cache.TryGetValue (c)
match exist with
| true ->
// Return the cached result directly, no method call
printfn "%O -> In cache" c
value
| _ ->
// Function call is required first followed by caching the result for next call with the same parameters
printfn "%O -> Not in cache, calling function..." c
let value = f c
cache.Add (c, value)
value
then
let f (x:array<_>) = x.Length
then
let g = memoization f
let a = g [|1|]
let b = g [|1|]
I (obviously!) want b to be the retrieved memoized value already calculated, but it recalculated it.
ok, fair enough, with a C# head on, that makes sense, we're back to nasty objects, so how do I memoize a function that takes an array of values?
I notice that lists works nicely
So whats so special about arrays?
The issue is that, by default, Dictionary uses reference equality to check whether an object is in the dictionary. This means that it will only work if you pass it the same array instance. The following gets the value from the cache:
let g = memoization f
let arr = [|1|]
let a = g arr
let b = g arr
If you want to memoize results based on the values in the array, you can use structural equality comparison instead. To do this, all you need to do is to pass HashIdentity.Structural as an argument to Dictionary. This uses an F#-library defined structural comparison that returns the same hash for arrays containing the same values:
let cache = Dictionary<_,_>(HashIdentity.Structural)
With this change, your original example will work as you wanted.
I have some code, 3 functions
ParseTemplate, ParseTemplates -> These two can be combined into one and will have to be to make this work I think.
And
loadTemplate
let ParseTemplate (template: Match) =
let templateName = template.Groups.[1] |> string
loadTemplate templateName
let ParseTemplates (string: string) =
Regex.Replace(string, "\[tpl\:(.*?)\]", MatchEvaluator ParseTemplate)
let rec loadTemplate templateName =
templateName
|> getTemplateFilePath
|> File.ReadAllText
|> ParseVariables
|> ParseArrays
|> ParseLanguageVariablesWithReplacements
|> ParseSimpleLanguageVariables
|> ParseTemplates
The problem is where to position these in the file/how to structure them differently, because as it is there's always a function calling a function below it (and therefore is not defined).
In this case
I like the loadTemplate function as it exists - it's very clean and readable and I'd rather avoid using lambda functions inside of it if possible. The problem is it calls ParseTemplates which can then call loadTemplate recursively.
Best way to approach?
What would be an elegant way to implement the functionality of this nested class in F#?
private class Aliaser {
private int _count;
internal Aliaser() { }
internal string GetNextAlias() {
return "t" + (_count++).ToString();
}
}
This was my first attempt, but it feels like there should be a sexy one-liner for this:
let aliases = (Seq.initInfinite (sprintf "t%d")).GetEnumerator()
let getNextAlias() =
aliases.MoveNext() |> ignore
aliases.Current
The usual way of writing is to create a function with local state captured in a closure:
let getNextAlias =
let count = ref 0
(fun () ->
count := !count + 1;
sprintf "t%d" (!count))
The type of getNextAlias is simply unit -> string and when you call it repeatedly, it returns strings "t1", "t2", ... This relies on mutable state, but the mutable state is hidden from the user.
Regarding whether you can do this without mutable state - the simple answer is NO, because when you call a purely functional function with the same parameter twice, it must return the same result. Thus, you'd have to write something with the following structure:
let alias, state1 = getNextAlias state0
printf "first alias %s" alias
let alias, state2 = getNextAlias state1
printf "second alias %s" alias
// ...
As you can see, you'd need to keep some state and maintain it through the whole code. In F#, the standard way of dealing with this is to use mutable state. In Haskell, you could use State monad, which allows you to hide the passing of the state. Using the implementation from this question, you could write something like:
let getNextAlias = state {
let! n = getState
do! setState (n + 1)
return sprintf "t%d" n }
let program =
state {
let! alias1 = getNextAlias()
let! alias2 = getNextAlias()
// ...
}
execute progam 0 // execute with initial state
This is quite similar to other computations such as lazy or seq, actually - computations in the state { .. } block have some state and you can execute them by providing initial value of the state. However, unless you have good reasons for requiring purely functional solution, I'd prefer the first version for practical F# programming.
Here is the quick and dirty translation
type Aliaser () =
let mutable _count = 0
member x.GetNextAlias() =
let value = _count.ToString()
_count <- _count + 1
"t" + value
A more functional approach without state is to use continuations.
let createAliaser callWithValue =
let rec inner count =
let value = "t" + (count.ToString())
callWithValue value (fun () -> inner (count + 1))
inner 1
This is a declaration which will call the function callWithValue with both the value and the function to execute to repeat with the next value.
And here's an example using it
let main () =
let inner value (next : unit -> unit )=
printfn "Value: %s" value
let input = System.Console.ReadLine()
if input <> "quit" then next()
createAliaser inner
main()
I would use Seq.unfold : (('a -> ('b * 'a) option) -> 'a -> seq<'b>) to generate the aliases.
Implemented as:
let alias =
Seq.unfold (fun count -> Some(sprintf "t%i" count, count+1)) 0
Is there a way to combine the 'cast' (box) operation as part of the same statement. Here is what I have currently:
let node = dTable.Call("treeNode")
let nodeobj = ((box node) :?> AxaptaObject)
let meth = nodeobj.Call("AOTFindChild", "Methods")
'box' is just a function, so you can pipe an expression to it, e.g.
dTable.Call("treenode") |> box :?> AxaptaObject
Is it possible to call a method on a returned object using the pipeline infix operator?
Example, I have a .Net class (Class1) with a method (Method1). I can currently code it like this:
let myclass = new Class1()
let val = myclass.Method1()
I know I could also code it as such
let val = new Class1().Method1()
However I would like to do be able to pipeline it (I am using the ? below where I don't know what to do):
new Class1()
|> ?.Method1()
Furthermore, say I had a method which returns an object, and I want to only reference it if that method didn't return null (otherwise bail?)
new Class1()
|> ?.Method1()
|> ?? ?.Method2()
Or to make it clearer, here is some C# code:
public void foo()
{
var myclass = new Class1();
Class2 class2 = myclass.Method1();
if (class2 == null)
{
return;
}
class2.Method2();
}
You can define something similar to your (??) operator fairly easily (but operators can't start with a question mark):
let (~??) f x =
if (x <> null) then
f x
Unfortunately, your pipelined code will need to be a bit more verbose (also, note that you can drop the new keyword for calling constructors):
Class1()
|> fun x -> x.Method1()
Putting it all together:
Class1()
|> fun x -> x.Method1()
|> ~?? (fun x -> x.Method2())
Using a custom operator as 'kvb' suggests is definitely an option. Another approach that you may find interesting in this case is to define your own 'computation expression' that automatically performs the check for null value at every point you specify. The code that uses it would look like this:
open System.Windows.Forms
// this function returns (0) null, or (1) btn whose parent is
// null or (2) button whose parent is not null
let test = function
| 1 -> new Button(Text = "Button")
| 2 -> new Button(Text = "Button", Parent = new Button(Text = "Parent"))
| _ -> null
let res =
safe { let! btn = test(2) // specify number here for testing
// if btn = null, this part of the computation will not execute
// and the computation expression immediately returns null
printfn "Text = %s" btn.Text
let! parent = btn.Parent // safe access to parent
printfn "Parent = %s" parent.Text // will never be null!
return parent }
As you can see, when you want to use a value that can potentially be 'null', you use let! inside the computation expression. The computation expression can be defined so that it immediately returns null if the value is null and runs the rest of the computation otherwise. Here is the code:
type SafeNullBuilder() =
member x.Return(v) = v
member x.Bind(v, f) =
if v = null then null else f(v)
let safe = new SafeNullBuilder()
BTW: If you want to learn more about this, it is very similar to 'Maybe' monad in Haskell (or computation working with F# option type).