How to use WhenAnyValue and ToProperty with F#? - xamarin

I'm new to F# and to reactiveui, can someone help me to translate the following C# code to F#
this.WhenAnyValue(e => e.Username, p => p.Password,
(emailAddress, password) => (!string.IsNullOrEmpty(emailAddress)) && !string.IsNullOrEmpty(password) && password.Length > 6)
.ToProperty(this, v => v.IsValid, out _isValid);
Here's what I tried, even I don't know if this is the right way
this.WhenAnyValue(toLinq <# fun (vm:LoginViewModel) -> vm.Username #>, toLinq <# fun (vm:LoginViewModel) -> vm.Password #>)
.Where(fun (u, p) -> (not String.IsNullOrEmpty(u)) && (not String.IsNullOrEmpty(p)) && p.Length > 6)
.Select(fun _ -> true)
.ToProperty(this, (fun vm -> vm.IsValid), &_isValid) |> ignore
And I'm getting this error:
Error: Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized

This happens because of this:
not String.IsNullOrEmpty(u)
Parentheses don't carry a special meaning in F# as they do in C#. In F# they're just parentheses, not a special syntax for calling methods. In other words, the above expression is equivalent to this:
not String.IsNullOrEmpty u
I think it ought to be obvious what the problem is now: this looks as if you're calling the not function with two arguments, whereas what you actually meant to do was this:
not (String.IsNullOrEmpty u)
Or this:
not <| String.IsNullOrEmpty u
Or, alternativeIy, you could create a special function for this:
let notEmpty = not << String.IsNullOrEmpty
// And then:
notEmpty u

Related

Composing F# code quotations programmatically

The following code is extracted from an application and adapted to highlight the issue as easy as possible
module Mo
open System
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Linq.RuntimeHelpers
open System.Linq.Expressions
type Type() =
member _.Prop1 with get() = 1
member _.Prop2 with get() = 2
let toFunc<'t when 't :> Type>(filter: 't -> Expr<bool>) =
let xp = <# Func<'t, bool>(fun (t: 't) -> %(filter t) && t.Prop2 = 2) #>
LeafExpressionConverter.QuotationToExpression xp |> unbox<Expression<Func<'t, bool>>>
let getFunc (i: int) =
let filter (t: Type) = <# t.Prop1 = i #>
toFunc filter
the problem is in the line
let xp = <# Func< 't, bool>(fun (t: 't) -> %(filter t) && t.Prop2 = 2) #>
The compiler complains in fun (t: 't) as follows:
Error FS0446
The variable 't' is bound in a quotation but is used as part of a spliced expression.
This is not permitted since it may escape its scope.
The intent is to compose quotations into a filter Linq expression.
Is there a (alternative) way to do this?
EDIT:
Some more context looks necessary:
The returned Func expression is later passed to Azure.Data.Tables.TableClient.Query(). Unfortunately this method doesn't support expressions containing function calls.
Converting filter to a quoted function (as suggested by Fyodor) was my first version, but I had to abandon it because of this requirement of the Azure Tables SDK.
So the question becomes :
Is it possible to achieve the result of an expression that doesn't contain calls to external method/function?
You're mixing up your variables between quotation realm and "regular" realm.
filter is not a quoted function. It's a regular function that returns a quotation. Regular functions get regular parameters, quoted functions get quoted parameters.
The t parameter here:
let xp = <# Func<'t, bool>(fun (t: 't) -> %(filter t) && t.Prop2 = 2) #>
^
|
This one
That's a quoted parameter. It's defined inside a quotation.
And yet, you're trying to pass its value to the filter function. But at the moment of constructing the quotation, the parameter t doesn't have a value yet! Only when you're done constructing the quotation, then compile it to IL, and then call it, - only then will the parameter t have a value, allowing you to call the filter function. But you need the result of filter function to finish constructing the quotation in the first place!
The most straightforward fix is to make filter a quoted function. Then you can splice it into the quotation, and then pass the parameter t to the result of splicing:
let toFunc<'t when 't :> Type>(filter: Expr<'t -> bool>) =
let xp = <# Func<'t, bool>(fun (t: 't) -> (%filter) t && t.Prop2 = 2) #>
LeafExpressionConverter.QuotationToExpression xp |> unbox<Expression<Func<'t, bool>>>
let getFunc (i: int) =
let filter = <# fun (t: Type) -> t.Prop1 = i #>
toFunc filter

F# using match to validate parameters

I'm learning F#. I want to know best practices for validating input parameters. In my naivety I had thought I could do something like this:
let foo = match bar with
| <test for valid> -> bar
| _ -> "invalid"
of course that doesn't work due to mismatching types. So I'd like to see the patterns experienced F# programmers use for this sort of thing. match? If/then/else?
Something else?
You are having problems because you are trying to bind a value to something that could be two possible types depending upon program flow - that is incompatible with static typing.
If I have some value foo, it cannot be, for example, a string OR an int depending upon program flow; it must resolve to exactly one type at compile time.
You can, however, use a discriminated union that can represent several different options within a single type.
Here is a summary of the approaches for doing just that.
Result Type / Either
F# 4.1, which is currently available via nuget, introduces the Result type. You may find this type referred to as Either in other languages.
It is defined like this:
[<Struct>]
type Result<'T,'TError> =
/// Represents an OK or a Successful result. The code succeeded with a value of 'T.
| Ok of ResultValue:'T
/// Represents an Error or a Failure. The code failed with a value of 'TError representing what went wrong.
| Error of ErrorValue:'TError
If you are pre-F# 4.1 (which is very likely). You can define this type yourself, although you must remove the [<Struct>] attribute.
You can then make a tryParseFloat function:
let tryParseFloat str =
match System.Double.TryParse str with
| true, f -> Ok f
| _ -> Error <| sprintf "Supplied string (%s) is not a valid float" str
You can determine success or failure:
match tryParseFloat "0.0001" with
|Ok v -> // handle success
|Error err -> // handle error
In my opinion, this is the preferred option, especially in F# 4.1+ where the type is built in. This is because it allows you to include information relating to how and why some activity failed.
Option Type / Maybe
The option type contains either Some 'T or simply None. The option type is used to indicate the presence or absence of a value, None fills a role similar to null in other languages, albeit far more safely.
You may find this type referred to as Maybe in other languages.
let tryParseFloat str =
match System.Double.TryParse str with
| true, f -> Some f
| _ -> None
You can determine success or failure:
match tryParseFloat "0.0001" with
|Some value -> // handle success
|None -> // handle error
Composition
In both cases, you can readily compose options or results using the associated map and bind functions in the Option and Result modules respectively:
Map:
val map: mapping:('T -> 'U) -> option:'T option -> 'U option
val map : mapping:('T -> 'U) -> result:Result<'T, 'TError> -> Result<'U, 'TError>
The map function lets you take an ordinary function from 'a -> 'b and makes it operate on results or options.
Use case: combine a result with a function that will always succeed and return a new result.
tryParseFloat "0.001" |> Result.map (fun x -> x + 1.0);;
val it : Result<float,string> = Ok 1.001
Bind:
val bind: binder:('T -> 'U option) -> option:'T option -> 'U option
val bind: binder:('T -> Result<'U, 'TError>) -> result:Result<'T, 'TError> -> Result<'U, 'TError>
The bind function lets you combine results or options with a function that takes an input and generates a result or option
Use case: combine a result with another function that may succeed or fail and return a new result.
Example:
let trySqrt x =
if x < 0.0 then Error "sqrt of negative number is imaginary"
else Ok (sqrt x)
tryParseFloat "0.001" |> Result.bind (fun x -> trySqrt x);;
val it : Result<float,string> = Ok 0.0316227766
tryParseFloat "-10.0" |> Result.bind (fun x -> trySqrt x);;
val it : Result<float,string> = Error "sqrt of negative number is imaginary"
tryParseFloat "Picard's Flute" |> Result.bind (fun x -> trySqrt x);;
val it : Result<float,string> =
Error "Supplied string (Picard's Flute) is not a valid float"
Notice that in both cases, we return a single result or option despite chaining multiple actions - that means that by following these patterns you need only check the result once, after all of your validation is complete.
This avoids a potential readability nightmare of nested if statements or match statements.
A good place to read more about this is the Railway Oriented Programming article that was mentioned to you previously.
Exceptions
Finally, you have the option of throwing exceptions as a way of preventing some value from validating. This is definitely not preferred if you expect it to occur but if the event is truly exceptional, this could be the best alternative.
The basic way of representing invalid states in F# is to use the option type, which has two possible values. None represents invalid state and Some(<v>) represents a valid value <v>.
So in your case, you could write something like:
let foo =
match bar with
| <test for valid> -> Some(bar)
| _ -> None
The match construct works well if <test for valid> is actual pattern (e.g. empty list or a specific invalid number or a null value), but if it is just a boolean expression, then it is probably better to write the condition using if:
let foo =
if <test for valid> bar then Some(bar)
else None
You could do something along this lines
type Bar =
| Bar of string
| Foo of int
let (|IsValidStr|_|) x = if x = Bar "bar" then Some x else None
let (|IsValidInt|_|) x = if x = Foo 0 then Some x else None
let foo (bar:Bar) =
match bar with
| IsValidStr x -> Some x
| IsValidInt x -> Some x
| _ -> None
That is you could use active patterns to check for the actual business rules and return an Option instance
Based on what the OP wrote in the comments:
You would define a type as in the post that Fyodor linked, that captures your two possible outcomes:
type Result<'TSuccess,'TFailure> =
| Success of 'TSuccess
| Failure of 'TFailure
Your validation code becomes:
let checkBool str =
match bool.TryParse str with
| true, b -> Success b
| _ -> Failure ("I can't parse this: " + str)
When using it, again use match:
let myInput = "NotABool"
match checkBool myInput with
| Success b -> printfn "I'm happy: %O" b
| Failure f -> printfn "Did not like because: %s" f
If you only would like to continue with valid bools, your code can only fail on invalid arguments, so you would do:
let myValidBool =
match checkBool myInput with
| Success b -> b
| Failure f -> failwithf "I did not like the args because: %s" f

How to define a wildcard pattern using cerl:c_clause

I'm trying to compile some personal language to erlang. I want to create a function with pattern matching on clauses.
This is my data :
Data =
[ {a, <a_body> }
, {b, <b_body> }
, {c, <c_body> }
].
This is what i want :
foo(a) -> <a_body>;
foo(b) -> <b_body>;
foo(c) -> <c_body>;
foo(_) -> undefined. %% <- this
I do that at the moment :
MkCaseClause =
fun({Pattern,Body}) ->
cerl:c_clause([cerl:c_atom(Pattern)], deep_literal(Body))
end,
WildCardClause = cerl:c_clause([ ??? ], cerl:c_atom(undefined)),
CaseClauses = [MkCaseClause(S) || S <- Data] ++ [WildCardClause],
So please help me to define WildCardClause. I saw that if i call my compiled function with neither a nor b nor c it results in ** exception error: no true branch found when evaluating an if expression in function ....
When i print my Core Erlang code i get this :
'myfuncname'/1 =
fun (Key) ->
case Key of
<'a'> when 'true' -> ...
<'b'> when 'true' -> ...
<'c'> when 'true' -> ...
end
So okay, case is translated to if when core is compiled. So i need to specify a true clause as in an if expression to get a pure wildcard. I don't know how to do it, since matching true in an if expression and in a case one are different semantics. In a case, true is not a wildcard.
And what if i would like match expressions with wildcards inside like {sometag,_,_,Thing} -> {ok, Thing}.
Thank you
I've found a way to do this
...
WildCardVar = cerl:c_var('_Any'),
WildCardClause = cerl:c_clause([WildCardVar], cerl:c_atom(undefined)),
...
It should work for inner wildcards too, but one has to be careful to give different variable names to each _ wildcard since only multiple _ do not match each other, variables do.
f(X,_, _ ) %% matches f(a,b,c)
f(X,_X,_X) %% doesn't

How to Convert Expr<'a -> 'b> to Expression<Func<'a, obj>>

I'm using F# 3.0 with .NET 4.5 beta, and I'm trying to convert an F# quotation of type Expr<'a -> 'b> to a LINQ Expression<Func<'a, 'b>>.
I've found several questions that have solutions to this problem, but those techniques don't seem to work any longer, presumably due to changes in either F# 3.0 or .NET 4.5.
Converting F# Quotations into LINQ Expressions
Expression<Func<T, bool>> from a F# func
In both cases, when I run the code from the solutions of either question, the following action throws an exception:
mc.Arguments.[0] :?> LambdaExpression
...where mc is a MethodCallExpression. The exception is:
System.InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.MethodCallExpressionN' to type 'System.Linq.Expressions.LambdaExpression'.
No, the extra "N" at the end of MethodCallExpressionN is not a typo. Does anyone have a suggestion? Thanks.
UPDATE
Here's a complete reproduction. It turns out this code works fine on an expression like <# fun x -> x + 1 #>. My problem is that in my case I need to convert an Expr<'a -> 'b> into Expr<'a -> obj> so that I don't have to litter all my lambda expressions with box. I did so by splicing the original expression into this one: <# %exp >> box #>. This produces an object with the correct type, but the code to convert to Expression<Func<'a, obj>> no longer works.
module Expr =
open System
open System.Linq.Expressions
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Linq.QuotationEvaluation
let rec private translateExpr (linq:Expression) =
match linq with
| :? MethodCallExpression as mc ->
let le = mc.Arguments.[0] :?> LambdaExpression
let args, body = translateExpr le.Body
le.Parameters.[0] :: args, body
| _ -> [], linq
let ToFuncExpression (expr:Expr<'a -> 'b>) =
let args, body = expr.ToLinqExpression() |> translateExpr
Expression.Lambda<Func<'a, 'b>>(body, Array.ofList args)
let exp = <# fun x -> x + 1 #>
let r = Expr.ToFuncExpression <# %exp >> box #>
printfn "%A" r
Can you post a more complete sample and also include the F# expression that you're trying to convert?
I tried to test the behaviour on .NET 4.5 using a minimal sample and it worked for me. Here is what I did:
I created new F# 3.0 project and copied Linq.fs and Linq.fsi from the 2.0 version of F# PowerPack. (Or is there a 3.0 version of the ToLinqExpression method available somewhere in F# 3.0?)
I used the code from Daniel's earlier answer and called the function as follows:
let r = toLinq <# fun x -> x + 1 #>
printfn "%A" r
This did not throw any exception and it printed x => (x + 1), which looks correct to me.
EDIT: To answer the updated question - both of the code samples that you referred to (mine and Daniel's) assume that the body of the quotation is an explicitly constructed function, so they only work on quotations of a specific structure: <# fun x -> ... #>.
You can fix the problem by using splicing in an explicitly constructed function. The following works for me:
let exp = <# fun x -> x + 1 #>
let r = toLinq <# fun a -> box ((%exp) a) #>
printfn "%A" r
This contains application of an F# function, so the generated Expression contains a call to ToFSharpFunc (which converts a delegate to an F# function) and then invocation of this. This may be an issue if you want Expression that standard .NET tools can understand (in which case, you'd have to post-process the C# expression tree and remove these constructs).

Haskell: Can I use a where clause after a block with bind operators (>>=)?

I have a very simple question. I'd like to use a where clause after a bloc of code that uses bind operators but I get a compilation error.
Here is a simple example:
main =
putStrLn "where clause test:" >>
return [1..10] >>= \list ->
print list'
where list' = reverse list -- test1.hs:5:28: Not in scope: `list'
I can use a let clause for list' as in
main =
putStrLn "where clause test:" >>
return [1..10] >>= \list ->
let list' = reverse list -- works of course
in print list'
but I'd really like it if I could use a where clause...
I also tried with do notation
main = do
putStrLn "where clause test:"
list <- return [1..10]
print list'
where list' = reverse list --test3.hs:5:30: Not in scope: `list'
Same problem. Can I use a where clause in these circumstances?
As ephemient explains, you can't use where clauses the way you do.
The error happens because in this code:
main =
return [1..10] >>= \list ->
print list'
where
list' = reverse list
The where-clause is attached to the main function.
Here's that same function with more parentheses:
main = return [1..10] >>= (\list -> print list')
where
list' = reverse list
I think its fairly obvious why you get the "out of scope" error: The binding for list is deep inside the main expression, not something the where clause can reach.
What I usually do in this situation (and I've been bitten by the same thing a bunch of times). I simply introduce a function and pass the list as an argument.
main = do
list <- return [1..10]
let list' = f list
print list'
where
f list = reverse list -- Consider renaming list,
-- or writing in point-free style
Of course, I imagine your actual code in the f function is a lot more that just reverse and that's why you want it inside a where clause, instead of an inline let binding. If the code inside the f function is very small, I'd just write it inside the let binding, and wouldn't go through the overhead of introducing a new function.
The problem is that let-in is an expression, which can be used inside other expressions, while where can only be used on a (module|class|instance|GADT|...) declaration or a (function|pattern) binding.
From the Haskell 98 report on declarations and bindings,
p | g1 = e1
| g2 = e2
…
| gm = em
where { decls }
is sugar for
p = let decls in
if g1 then e1 else
if g2 then e2 else
…
if gm then em else error "Unmatched pattern"
or, simplifying things by removing guards,
p = e where { decls }
is sugar for
p = let decls in e
in both function and pattern bindings. This is true even when your e is a do {…} construct.
If you want to have a binding local to a particular subexpression within a larger expression, you need to use let-in (or simply let inside a do, but that's just sugar for let-in).
You can't even write
main = do
putStrLn "where clause test: "
list <- return [1..10]
(print list' where list' = reverse list)
because "e where { decls }" is not a legal expression – where can only be used in declarations and bindings.
main = do
putStrLn "where clause test: "
list <- return [1..10]
let list' = list'' where list'' = reverse list
print list'
This is legal (if somewhat contrived).
As far as I can tell, the where clause is only used in local bindings. The inner part of a >>(=) binding statement is not a local binding (two different kinds of bindings in that sentence).
Compare with this:
main = f [1..10]
f list =
putStrLn "where clause test:" >> print list'
where list' = reverse list
You might want to refer to the Haskell 98 syntax report - not sure how much help it would be.
If I'm wrong, someone will certainly correct me, but I'm pretty sure you can't use a where clause at all in the style you've shown above. list will never be in scope to a where clause unless it's a parameter to the function.

Resources