I was trying to write a function that solves following;
persistence 39 = 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit
persistence 999 = 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2
persistence 4 = 0 // because 4 is already a one-digit number
After I solved the question I tried to make all functions looks like Ramda.js function styles like this;
This code works;
let multiply = List.reduce (*)
let gt from input = input > from
let just input = fun _ -> input
let ifElse cond trueFn falseFn input =
if cond input then trueFn input else falseFn input
let digits n =
(string n) |> Seq.toList |> List.map (System.Char.GetNumericValue >> int)
let rec persRec iter current =
current
|> digits
|> multiply
|> ifElse (gt 9) (persRec (iter + 1)) (just iter)
let persistence n = if n > 9 then persRec 1 n else 0
But when I tried to modify persRec function with a curried composed version like following, it makes this stack overflow.
let rec persRec iter =
digits
>> multiply
>> ifElse (gt 9) (persRec (iter + 1)) (just iter)
What's wrong with this?
The function persRec is calling itself unconditionally. Here:
>> ifElse (gt 9) (persRec (iter + 1)) (just iter)
^^^^^^^^^^^^^^^^^^^^
|
unconditional recursive call
This happens always. Every time persRec is called by somebody, it immediately calls itself right away.
You may expect that the recursive call should only happen when gt 9, because, after all, it's inside an ifElse, right? But that doesn't matter: ifElse is not special, it's just a function. In order to call a function, F# has to compute all its parameter before the call (aka "applicative order of evaluation"), which means it has to call persRec (iter + 1) before it can call ifElse, and it has to call ifElse before it can call (>>), and it has to call (>>) in order to compute result of persRec. So ultimately, it needs to call persRec in order to compute the result of persRec. See where this is going?
The previous version works, because the body of persRec is not actually executed before the call to ifElse. The body of persRec will only be executed when all its parameters are supplied, and the last parameter will only be supplied inside the body of ifElse when the condition is true.
The way I see it, the confusion stems from the difference between denotational and operational semantics. Yes, mathematically, logically, the functions are equivalent. But execution also matters. Normal vs. applicative evaluation order. Memory concerns. Performance. Those are all outside of the domain of lambda-calculus.
Related
I want to generalize some predicate written in swi-prolog to calculate the power of some function. My predicate so far is:
% calculates the +Power and the +Argument of some function +Function with value +Value.
calc_power(Value, Argument, Function, Power) :-
not(Power is 0),
Power is Power_m1 + 1,
Value =..[Function, Buffer],
calc_power(Buffer, Argument, Function, Power_m1), !.
calc_power(Argument, Argument, _, 0).
The call calc_power((g(a)),A,f,POW). gives so far:
A = g(a),
POW = 0.
My generalization should also solve calls like that:
calc_power(A1, a, f, 3).
the solution should be in that special calse A1 = f(f(f(a))). But for some reason it doesn't work. I get the error:
ERROR: Arguments are not sufficiently instantiated
in line
Power is Power_m1 + 1
it means probably in swi prolog it is not possible to take plus with two variables. How can I solve this problem?
Can delay the + 1 operation with:
int_succ(I0, I1) :-
( nonvar(I0) ->
integer(I0),
I0 >= 0,
I1 is I0 + 1
; nonvar(I1) ->
integer(I1),
I1 >= 1,
I0 is I1 - 1
; when((nonvar(I0) ; nonvar(I1)), int_succ(I0, I1))
).
Example in swi-prolog:
?- int_succ(I0, I1), I1 = 7.
I0 = 6,
I1 = 7.
This is more flexible than https://www.swi-prolog.org/pldoc/man?predicate=succ/2 , and can of course be modified to support negative numbers if desired.
Found some solution
:- use_module(library(clpfd)).
% calculates the +Power and the +Argument of some function +Function with value +Value.
calc_power(Argument, Argument, _, 0).
calc_power(Value, Argument, Function, Power) :-
Power #\= 0,
Power #= Power_m1 + 1,
Value =..[Function, Buffer],
calc_power(Buffer, Argument, Function, Power_m1).
I've got a function that needs to work out the minimum change required to break down a certain amount of money.
A user would enter a value of money and the possible denominations, and it would output how many of each denomination would be needed to make up the money eg.
> coinChange 34 [1, 5, 10, 25, 50, 100]
[4,1,0,1,0,0]
Here is what I have so far:
coinChange :: Integer -> [Integer] -> [Integer]
coinChange _ [] = []
coinChange 0 xs = []
coinChange v xs = do
dropWhile (>v) (reverse xs)
createNewList :: Integer -> [Integer]
createNewList 0 = []
createNewList x = 0 : createNewList (x - 1)
I have a separate function called createNewList which I want to call to set up a new list of 0s at the beginning.
However, because I plan on making coinChange a recursive function when working out how much money is left, if I just call makeNewList in coinChange, at the moment it would reset the list because it would be called every recursion.
So my question is, is there a way to make a function call another function only once, before proceeding with the recursion.
Hope I've made it clear, thanks
In general you are allowed to create local helper functions in Haskell. Maybe this example will inspire you:
prepareData x = if x < 0 then -x else x
mainFunction n =
let recursiveLocalFunction x =
if x < 2 then 1 else x * recursiveLocalFunction (x - 1)
in recursiveLocalFunction (prepareData n)
I would like to know why does ocaml evaluate the calls from right to left, is that a FP principle or it doesn't matter at all to a FP language ?
A quicksort example :
let rec qs = function
| [] -> []
| h::t -> let l, r = List.partition ((>) h) t in
List.iter (fun e -> print_int e; print_char ' ') l; Printf.printf " <<%d>> " h;
List.iter (fun e -> print_int e; print_char ' ') r; print_char '\n';
(qs l)#(h::qs r)
In my example the call to (qs r) is evaluated first and then (qs l) but I expected it to be otherwise.
# qs [5;43;1;10;2];;
1 2 <<5>> 43 10
10 <<43>>
<<10>>
<<1>> 2
<<2>>
- : int list = [1; 2; 5; 10; 43]
EDIT :
from https://caml.inria.fr/pub/docs/oreilly-book/html/book-ora029.html
In Objective CAML, the order of evaluation of arguments is not
specified. As it happens, today all implementations of Objective CAML
evaluate arguments from left to right. All the same, making use of
this implementation feature could turn out to be dangerous if future
versions of the language modify the implementation.
The order of evaluation of arguments to a function is not specified in OCaml.
This is documented in Section 6.7 of the manual.
In essence this gives the greatest possible freedom to the system (compiler or interpreter) to evaluate expressions in an order that is advantageous in some way. It means you (as an OCaml programmer) must write code that doesn't depend on the order of evaluation.
If your code is purely functional, its behavior can't depend on the order. So you need to be careful only when writing code with effects.
Update
If you care about order, use let:
let a = <expr1> in
let b = <expr2> in
f a b
Or, more generally:
let f = <expr0> in
let a = <expr1> in
let b = <expr2> in
f a b
Update 2
For what it's worth, the book you cite above was published in 2002. A lot has changed since then, including the name of the language. A more current resource is Real World OCaml.
I have the following code:
- exception Negative of string;
> exn Negative = fn : string -> exn
- local fun fact 0 =1
| fact n = n* fact(n-1)
in
fun factorial n=
if n >= 0 then fact n
else
raise Negative "Insert a positive number!!!"
handle Negative msg => 0
end;
What is wrong with it?? I get the error:
! Toplevel input:
! handle Negative msg => 0
! ^
! Type clash: expression of type
! int
! cannot have type
! exn
How can I fix it? I want the function to return 0, by means of exceptions, if the user enters a negative number.
I am also wondering how to display a message when the user enters a negative number, since print() returns unit, but the rest of the function returns int;
The precedence of raise and handle is a bit weird in SML. What you have written groups as
raise ((Negative "...") handle Negative msg => 0)
Consequently, you need to add parentheses around the if to get the right meaning.
On the other hand, I don't understand why you raise an exception just to catch it right away. Why not simply return 0 in the else branch?
Edit: If you want to print something and then return a result, use the semicolon operator:
(print "error"; 0)
However, I would strongly advise against doing that inside the factorial function. It's better to keep I/O and error handling separate from basic computational logic.
Here is a number of ways you can fix your code:
local
fun fact 0 = 1
| fact n = n * fact (n-1)
in
(* By using the built-in exception Domain *)
fun factorial n =
if n < 0 then raise Domain else fact n
(* Or by defining factorial for negative input *)
fun factorial n =
if n < 0 then -1 * fact (-n) else fact n
(* Or by extending the type for "no result" *)
fun factorial n =
if n < 0 then NONE else SOME (fact n)
end
I'm an OCaml noob. I'm trying to figure out how to handle a comparison operator that's passed into a function.
My function just tries to pass in a comparison operator (=, <, >, etc.) and an int.
let myFunction comparison x =
if (x (comparison) 10) then
10
else
x;;
I was hoping that this code would evaluate to (if a "=" were passed in):
if (x = 10) then
10
else
x;;
However, this is not working. In particular, it thinks that x is a bool, as evidenced by this error message:
This expression has type 'a -> int -> bool
but an expression was expected of type int
How can I do what I'm trying to do?
On a side question, how could I have figured this out on my own so I don't have to rely on outside help from a forum? What good resources are available?
Comparison operators like < and = are secretly two-parameter (binary) functions. To pass them as a parameter, you use the (<) notation. To use that parameter inside your function, you just treat it as function name:
let myFunction comp x =
if comp x 10 then
10
else
x;;
printf "%d" (myFunction (<) 5);; (* prints 10 *)
OCaml allows you to treat infix operators as identifiers by enclosing them in parentheses. This works not only for existing operators but for new ones that you want to define. They can appear as function names or even as parameters. They have to consist of symbol characters, and are given the precedence associated with their first character. So if you really wanted to, you could use infix notation for the comparison parameter of myFunction:
Objective Caml version 3.12.0
# let myFunction (#) x =
x # 10;;
val myFunction : ('a -> int -> 'b) -> 'a -> 'b = <fun>
# myFunction (<) 5;;
- : bool = true
# myFunction (<) 11;;
- : bool = false
# myFunction (=) 10;;
- : bool = true
# myFunction (+) 14;;
- : int = 24
#
(It's not clear this makes myFunction any easier to read. I think definition of new infix operators should be done sparingly.)
To answer your side question, lots of OCaml resources are listed on this other StackOverflow page:
https://stackoverflow.com/questions/2073436/ocaml-resources
Several possibilities:
Use a new definition to redefine your comparison operator:
let myFunction comparison x =
let (#) x y = comparison x y in
if (x # 10) then
10
else
x;;
You could also pass the # directly without the extra definition.
As another solution you can use some helper functions to define what you need:
let (/*) x f = f x
let (*/) f x = f x
let myFunction comparison x =
if x /* comparison */ 10 then
10
else
x