I have a function findEntryByAddress which has an inline declararation of filterEntry. I would like to add another boolean check, but then there would be too many chars in one line.
How can I split the boolean expression, one equals check per line.
findEntryByAddress :: Address -> AddressBook -> Maybe Entry
findEntryByAddress = head <<< filter filterEntry
where
filterEntry :: Entry -> Boolean
filterEntry entry = entry.firstName == firstName && entry.lastName == lastName
I have checked Haskell's Indentation guide, nothing on multiline expressions.
code from purescript-book.
I'm not sure I understand the question, you want to do something like this?
findEntryByAddress :: Address -> AddressBook -> Maybe Entry
findEntryByAddress = head <<< filter filterEntry
where
filterEntry :: Entry -> Boolean
filterEntry entry = entry.firstName == firstName &&
entry.lastName == lastName &&
entry.age == age
In a where, you can jump a line but you have to put the rest of the expression one space after the beginning of the definition otherwise Haskell will think you're defining something new. So this is correct:
where f = x &&
y
But this isn't:
where f = x &&
y
By the way, in Haskell, there is no Boolean type, the type of True and False is Bool.
Related
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
I'm working/testing streams in Java8 and come across very frustrating issue.
I've got the code which compiles well:
List<String> words = Arrays.asList("Oracle", "Java", "Magazine");
List<String> wordLengths = words.stream().map((x) -> x.toUpperCase())
.collect(Collectors.toList());
And second one (nearly the same) which throw a warnings:
List<String> words = Arrays.asList("Oracle", "Java", "Magazine");
List<String> wordLengths = words.stream().map((x) -> {
x.toUpperCase();
}).collect(Collectors.toList());
Warning:
The method map(Function<? super String,? extends R>) in the type Stream<String> is not applicable for the arguments ((<no type> x) -> {})
What does this additional brackets have changed?
Your lambda expression returns a value. If you use brackets you need to add a return statement to your lambda function:
List<String> words = Arrays.asList("Oracle", "Java", "Magazine");
List<String> wordLengths = words.stream().map((x) -> {
return x.toUpperCase();
}).collect(Collectors.toList());
According to the official Oracle tutorial
A lambda expression consists of the following:
A comma-separated list of formal parameters enclosed in parentheses.
The CheckPerson.test method contains one parameter, p, which
represents an instance of the Person class.
Note: You can omit the data type of the parameters in a lambda
expression. In addition, you can omit the parentheses if there is only
one parameter. For example, the following lambda expression is also
valid:
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
The arrow token, ->
A body, which consists of a single expression or a statement block.
This example uses the following expression:
p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
If you specify a single expression, then the Java runtime evaluates
the expression and then returns its value. Alternatively, you can use
a return statement:
p -> {
return p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25;
}
A return statement is not an expression; in a lambda expression, you
must enclose statements in braces ({}). However, you do not have to
enclose a void method invocation in braces. For example, the following
is a valid lambda expression:
email -> System.out.println(email)
Since there is only one parameter in the provided lambda expression (x) -> x.toUpperCase() we can omit the parentheses: x -> x.toUpperCase(). String#toUpperCase returns a new String so there is no need to use return statement and braces. If instead we had a complex block with return statements we would have to enclose it into braces. Moreover in this case it is better to use Method Reference String::toUpperCase
List<String> wordLengths = words.stream().map(String::toUpperCase).collect(Collectors.toList());
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
I am trying to join a list of names:
List<String> names;
names = books.stream()
.map( b -> b.getName() )
.filter( n -> ( (n != null) && (!n.isEmpty()) ) )
.collect(Collectors.joining(", "));
This does not compile saying:
incompatible types. inference variable R has incompatible bounds
So after some research, it seems that there is something I misunderstood. I thought that .map( b -> b.getName() ) returned/changed the type to a String, and it seems something is wrong there. If I use .map(Book::getName) instead, I still get an error, but I probably don't fully understand the difference.
However, this does not complain:
List<String> names;
names = books.stream()
.map( b -> b.getName() )
.map( Book::getName )
.filter( n -> ( (n != null) && (!n.isEmpty()) ) )
.collect(Collectors.joining(", "));
Can someone explain me why? Some didactic explanation about differences between .map( b -> b.getName() ) and .map(Book::getName) are appreciated too, since I think I didn't get it right.
The joining(", ") collector will collect and join all Strings into a single string using the given separator. The returning type of collect in this case is String, but you are trying to assign the result to a List. If you want to collect Strings into a List, use Collectors.toList().
If you have a collection with Book instances, then it will be enough to map a stream of Books to a stream of Strings once.
Difference between lamdba & method refrence
A lamdba expression may be written as a block, containing multiple operations:
b -> {
// here you can have other operations
return b.getName();
}
if lambda has single operation, it can be shortened:
b -> b.getName()
Method reference is just a "shortcut" for a lambda with a single operation. This way:
b -> b.getName()
can be replaced with:
Book::getName
but if you have a lambda like this:
b -> b.getName().toLowerCase()
you cant use a reference to the getName method, because you are making and additional call to toLowerCase().
If you are using Collectors.joining(), the result will be a single concatenated String:
String names = books.stream()
.map( b -> b.getName() )
.filter(n -> (n != null) && !n.isEmpty())
.collect(Collectors.joining(", "));
The Collectors.toList() is the one that returns a List:
List<String> namesList = books.stream()
.map( b -> b.getName() )
.filter(n -> (n != null) && !n.isEmpty())
.collect(Collectors.toList());
Book::getName is a method reference and will have the same result as b -> b.getName(). Method reference is clearer and enables to pass other existing methods as a parameter to methods such as map(), as long as the passed method conforms to the signature of the expected functional interface. In this case, map() expects an instance of the Function interface. Thus, you can give any reference to a method that conforms to the signature of the abstract R apply(T t) method from such an interface.
Since you are mapping a Book to a String, the actual signature for the method to be given to the map() must be String apply(Book t). This can be read as "receive a Book and return a String". This way, any method you pass that conforms to this definition is valid. When you pass a method reference Book::getName, the getName method itself doesn't conform to the signature presented above (because it has no parameter at all), but it conforms to the definition of such a signature: you pass a book and return a String from its name.
Thus, consider that, inside the class where you have your book list, you also have a method which performs any operation over a Book, returning a String. The method below is an example that receives a Book and gets the first 10 characters from its name:
public String getReducedBookName(Book b){
if(b.getName() == null)
return "";
String name = b.getName();
return name.substring(0, name.length() > 10 ? 10 : name.length());
}
You can also pass this method (which is not inside the Book class) as parameter to the map() method:
String names = books.stream()
.map(this::getReducedBookName)
.filter(n -> !n.isEmpty())
.collect(Collectors.joining(", "));
if you prefer mapping over map
as String
String names = books.stream().collect(mapping(Book::getName,
filtering(s -> s != null && ! s.isBlank(),
joining(", "))));
as List
List<String> names = books.stream().collect(mapping(Book::getName,
filtering(s -> s != null && ! s.isBlank(),
toList())));
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