How to apply try and catch on a function? - erlang

I would like to know if it possible to apply a try catch expression on this function:
add(X, Y) ->
X + Y.
Here the user can provide a string instead of an integer.
Another example:
myfunction(X, Y) ->
case X == Y of
true -> X + Y;
false -> X * Y
end.
I just gave those example to know if it's possible or no and how?

Yes, you can certainly use try-catch in those functions. Here what it would look like:
add(X,Y) ->
try X + Y of
Z ->
Z
catch
error:badarith ->
badargs
end.
If your concerned about values of other types being passed in, a better solution would be to add some guards to the function instead:
add(X,Y) when is_number(X), is_number(Y) ->
X + Y.
This ensures that if the function body (X + Y) is only evaluated with numbers. If something other than a number is passed as either of these arguments the process will crash with a "no function clause matching" error. This is the Erlang way of ensuring the types are correct. While Erlang is dynamically typed, but you should generally know ahead of time if the values you have are suitable for the operation you are about to perform. That said, there are times you might not know the types if the variables you have, and in such cases wrapping the call in a case statement handles incorrect types:
case {X, Y} ->
{X, Y} when is_number(X), is_number(Y) ->
% safe to call add/2
add(X, Y);
_ ->
% values aren't both numbers, so we can't add them
nocanadd
end
The second function in your question myfunction/2 really should use guards too. Like this:
myfunction(X,Y) when is_number(X), is_number(Y) ->
case X == Y of
true -> X + Y;
false -> X * Y
end.

Related

Functional increment

I am working on a simple function that should, given x, return a tuple (y, z) such that y <= abs(5) + z * 10 = x, where z the smallest possible value.
In C, I would loop over z++ and y++, until their sum matches x.
Currently, I am trying to solve this problem functionally. Please consider the following example:
let foo x =
let rec aux (y, z, q) =
match (y + z * 10) with
q -> (y, z)
|_ -> aux(y + 1, z + 1, q) //How to correctly set the increments?
aux(0, 0, x)
This approach always returns (0, 0), no matter what. I referred to this question, while thinking a solution. I am aware that mutable variables should be avoided, and that is what I do. Unfortunately, I am afraid I missed the point, somewhere, thus I am approaching the problem from the wrong side.
You're introducing a new q binding for the result of the expression evaluated in your first case match rather than comparing against it. What you want is something like this:
match (y + z * 10) with
| r when r = q -> (y, z)
| _ -> aux(y + 1, z + 1, q)
In F# you are generally either within a value expression or a pattern matching expression. When you do this:
match (y + z * 10) with
q -> (y, z)
You're effectively saying: "Calculate y + z * 10 and then always assign the result to a new variable q, ignore this new variable and return (y, z)". This is because q is written in a pattern matching expression as it's just after with.
This is also why you're getting a warning on the next line saying "This rule will never by matched". This is a very common misunderstanding when people are learning F#.
You're not really making use of pattern matching at all when you do this. So I would recommend using an if expression instead:
if y + z * 10 = q
then (y, z)
else aux (y + 1, z + 1, q)
This is actually equivalent to using the ternary operators ? and : in C because it's an expression, not a statement, but it reads more clearly.

Definition style preferences

What is the preferable style for F# definitions?
The book I am studying makes regular use the following style:
let foo = fun x y ->
let aux1 = fun z -> z * 2
in aux1 x +
let aux2 = fun q -> q * 3
in aux2 y;;
On the other side, when I look for information on the web, it is most likely to meet something like:
let foo (x: int) (y: int) =
let aux1 (z:int) = z * 2
in aux1 x +
let aux2 (q: int) = q * 3
in aux2 y;;
On the Guide I failed to find a reference about it. Is it a matter that goes beyond "mere style"? There are efficiency implications behind these two approaches?
What does your experience suggest?
As a general rule, F# function definitions tend to do one of two things:
Define as few types as possible (let foo x y = ...). This is the case for most functions. Or...
Explicitly define the types of each argument and the return type (let foo (x : int) (y : int) : int = ....
Style #2 is rare, and I've usually seen it for functions that are explicitly part of the API of a module, and that have /// comments to provide documentation as well. For internal functions, though, the typeless variant is usually used, since F#'s type inference works so well.
Also, as s952163 pointed out in a comment, the in keyword is almost never used anymore, since the #light style makes it unnecessary. I'd expect to see your sample code written as follows in modern F# style:
let foo x y =
let aux1 z = z * 2
let aux2 q = q * 3
(aux1 x) + (aux2 y)
No ;; necessary, either, unless you're typing into the F# Interactive console. If you're using VS Code + Ionide, and highlighting segments of code and pressing Alt + Enter to send them to F# Interactive, then you don't need any ;; separators because Ionide adds them automatically.
I found evidence suggesting that the first style, even if today unconventional, is intrinsically connected to currying and anonymous functions.
Currying is a powerful characteristic of F#, where, I remember, every function could take only one parameter. For example:
let add x y = x + y
val add: int -> int -> int
The signature is interpreted as add is a function that takes two integers as input and return an integer.
When compile time comes, the function is interpreted like:
let add2 = fun x -> fun y -> x + y
val add2: int -> int -> int
where val add2: int -> int -> int is semantically equivalent to val add: (int -> (int -> int))
By providing an argument to add2, such as 6, it returns fun y -> 6 + y, which is another function waiting for its argument, while x is replaced by 6.
Currying means that every argument actually returns a separate function: that's why when we call a function with only few of its parameters returns another function.
If I got it correctly, the more common F# syntax of the second example, let add x y = x + y, could be thought like syntactic sugar for the explicit currying style shown above.

Techniques to Eliminate Duplicate Matching Logic in F#

When designing union type hierarchies, there seems to be potential for a considerable amount of logic duplication. For a simple and somewhat contrived example, consider the following type that represents a "flexible" number:
type Number =
|Integer of int
|Real of float
static member (+) (x : Number, y:Number) =
match x,y with
|Integer(x), Integer(y) -> Integer(x + y)
|Integer(x), Real(y) -> Real(float x + y)
|Real(x), Integer(y) -> Real(x + float y)
|Real(x), Real(y) -> Real(x + y)
static member (-) (x : Number, y:Number) =
match x,y with
|Integer(x), Integer(y) -> Integer(x - y)
|Integer(x), Real(y) -> Real(float x - y)
|Real(x), Integer(y) -> Real(x - float y)
|Real(x), Real(y) -> Real(x - y)
Additional operators will contain similarly repetitive matching logic. Is there a pattern/practice that can be applied to consolidate the logic in one function to eliminate such redundancy?
(Note: I realize that there are better ways of dealing with generic arithmetic in F#; this example should be considered just as an illustration of the general "how do I stop repeating myself?" problem in the context of pattern matching)
You could abstract over (+) and (-) by writing one function that takes the integer and floating arithmetic operators as arguments:
static member binOp (intOp : int -> int -> int) (floatOp : float -> float -> float) (x : Number, y:Number) =
match x,y with
|Integer(x), Integer(y) -> Integer(intOp x y)
|Integer(x), Real(y) -> Real(floatOp (float x) y)
|Real(x), Integer(y) -> Real(floatOp x (float y))
|Real(x), Real(y) -> Real(floatOp x y)
static member (+) (x,y) = Number.binOp (+) (+) (x,y)
static member (-) (x,y) = Number.binOp (-) (-) (x,y)
The same function should work fine for (*) as well. But when you get to (/) the pattern starts to break down because you probably want a floating point result even for integer inputs.
In my experience it's often simpler just to live with the duplication - it's usually not that bad in practice and trying to abstract too much leads to unreadable code.
In some cases where individual pattern-match cases get quite complex, active patterns can help you abstract the pattern once. I don't think they make sense in your specific example but they're worth keeping in mind.

Easy way to break foldl

I need to break from foldl. Here is a dummy example how to break from fold when I count sum of values in a list and meet too big value (i.e. 10)
L = [1,2,3,4,10,5,6,7],
Res =
try
lists:foldl(
fun(I, Value) ->
if (I < 10) ->
Value + I;
true ->
throw({too_big_value, Value})
end
end,
0, L)
catch
throw:{too_big_value, Value} -> Value
end,
Res.
I know this example is artificial but are there any nice method to break out fold (I know that fold always scan the whole structure)?
Please note, that i need to retrieve correct data even if i break from fold. In this case i should get data from previous iteration (as it done in my example).
Just curious, what is the point of using foldl here? If you need to break out, use recursion, foldl is not designed for it.
main([]) ->
L = [1,2,3,4,5,10,6,7],
io:format("[~w]", [s(L, 0)]).
s([], S) ->
S;
s([H|T], S) ->
if (H < 10) ->
s(T, S + H);
true ->
S
end.
Update:
Another options is to use takewhile:
lists:foldl(fun(E, A) -> A + E end, 0, lists:takewhile(fun(E) -> E < 10 end, L))
You're doing it right, using a throw with try/catch for nonlocal return. If the function looked at the return value from the fun to decide whether or not to continue, it wouldn't be foldl anymore.

F# Power issues which accepts both arguments to be bigints

I am currently experimenting with F#. The articles found on the internet are helpful, but as a C# programmer, I sometimes run into situations where I thought my solution would help, but it did not or just partially helped.
So my lack of knowledge of F# (and most likely, how the compiler works) is probably the reason why I am totally flabbergasted sometimes.
For example, I wrote a C# program to determine perfect numbers. It uses the known form of Euclids proof, that a perfect number can be formed from a Mersenne Prime 2p−1(2p−1) (where 2p-1 is a prime, and p is denoted as the power of).
Since the help of F# states that '**' can be used to calculate a power, but uses floating points, I tried to create a simple function with a bitshift operator (<<<) (note that I've edit this code for pointing out the need):
let PowBitShift (y:int32) = 1 <<< y;;
However, when running a test, and looking for performance improvements, I also tried a form which I remember from using Miranda (a functional programming language also), which uses recursion and a pattern matcher to calculate the power. The main benefit is that I can use the variable y as a 64-bit Integer, which is not possible with the standard bitshift operator.
let rec Pow (x : int64) (y : int64) =
match y with
| 0L -> 1L
| y -> x * Pow x (y - 1L);;
It turns out that this function is actually faster, but I cannot (yet) understand the reason why. Perhaps it is a less intellectual question, but I am still curious.
The seconds question then would be, that when calculating perfect numbers, you run into the fact that the int64 cannot display the big numbers crossing after finding the 9th perfectnumber (which is formed from the power of 31). I am trying to find out if you can use the BigInteger object (or bigint type) then, but here my knowledge of F# is blocking me a bit. Is it possible to create a powerfunction which accepts both arguments to be bigints?
I currently have this:
let rec PowBigInt (x : bigint) (y : bigint) =
match y with
| bigint.Zero -> 1I
| y -> x * Pow x (y - 1I);;
But it throws an error that bigint.Zero is not defined. So I am doing something wrong there as well. 0I is not accepted as a replacement, since it gives this error:
Non-primitive numeric literal constants cannot be used in pattern matches because they
can be mapped to multiple different types through the use of a NumericLiteral module.
Consider using replacing with a variable, and use 'when <variable> = <constant>' at the
end of the match clause.
But a pattern matcher cannot use a 'when' statement. Is there another solution to do this?
Thanks in advance, and please forgive my long post. I am only trying to express my 'challenges' as clear as I can.
I failed to understand why you need y to be an int64 or a bigint. According to this link, the biggest known Mersenne number is the one with p = 43112609, where p is indeed inside the range of int.
Having y as an integer, you can use the standard operator pown : ^T -> int -> ^T instead because:
let Pow (x : int64) y = pown x y
let PowBigInt (x: bigint) y = pown x y
Regarding your question of pattern matching bigint, the error message indicates quite clearly that you can use pattern matching via when guards:
let rec PowBigInt x y =
match y with
| _ when y = 0I -> 1I
| _ -> x * PowBigInt x (y - 1I)
I think the easiest way to define PowBigInt is to use if instead of pattern matching:
let rec PowBigInt (x : bigint) (y : bigint) =
if y = 0I then 1I
else x * PowBigInt x (y - 1I)
The problem is that bigint.Zero is a static property that returns the value, but patterns can only contain (constant) literals or F# active patterns. They can't directly contain property (or other) calls. However, you can write additional constraints in where clause if you still prefer match:
let rec PowBigInt (x : bigint) (y : bigint) =
match y with
| y when y = bigint.Zero -> 1I
| y -> x * PowBigInt x (y - 1I)
As a side-note, you can probably make the function more efficent using tail-recursion (the idea is that if a function makes recursive call as the last thing, then it can be compiled more efficiently):
let PowBigInt (x : bigint) (y : bigint) =
// Recursive helper function that stores the result calculated so far
// in 'acc' and recursively loops until 'y = 0I'
let rec PowBigIntHelper (y : bigint) (acc : bigint) =
if y = 0I then acc
else PowBigIntHelper (y - 1I) (x * acc)
// Start with the given value of 'y' and '1I' as the result so far
PowBigIntHelper y 1I
Regarding the PowBitShift function - I'm not sure why it is slower, but it definitely doesn't do what you need. Using bit shifting to implement power only works when the base is 2.
You don't need to create the Pow function.
The (**) operator has an overload for bigint -> int -> bigint.
Only the second parameter should be an integer, but I don't think that's a problem for your case.
Just try
bigint 10 ** 32 ;;
val it : System.Numerics.BigInteger =
100000000000000000000000000000000 {IsEven = true;
IsOne = false;
IsPowerOfTwo = false;
IsZero = false;
Sign = 1;}
Another option is to inline your function so it works with all numeric types (that support the required operators: (*), (-), get_One, and get_Zero).
let rec inline PowBigInt (x:^a) (y:^a) : ^a =
let zero = LanguagePrimitives.GenericZero
let one = LanguagePrimitives.GenericOne
if y = zero then one
else x * PowBigInt x (y - one)
let x = PowBigInt 10 32 //int
let y = PowBigInt 10I 32I //bigint
let z = PowBigInt 10.0 32.0 //float
I'd probably recommend making it tail-recursive, as Tomas suggested.

Resources