Standard ML exceptions - exception

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

Related

Type casting within a recursive function in Haskell

I am learning Haskell and recursion and different types in Haskell is making my brain hurt. I am trying to create a recursive function that will take a 32 bit binary number string and convert it to a decimal number. I think my idea for how the recursion will work is fine but implementing it into Haskell is giving me headaches. This is what I have so far:
bin2dec :: String -> Int
bin2dec xs = ""
bin2dec (x:xs) = bin2dec xs + 2^(length xs) * x
The function is supposed to take a 32 bit number string and then take off the first character of the string. For example, "0100101010100101" becomes "0" and "100101010100101". It then should turn the first character into a integer and multiply it by 2^length of the rest of the string and add it to the function call again. So if the first character in the 32 bit string is "1" then it becomes 1 * 2^(31) + recursive function call.
But, whenever I try to compile it, it returns:
traceProcP1.hs:47:14: error:
* Couldn't match type `[Char]' with `Int'
Expected: Int
Actual: String
* In the expression: ""
In an equation for `bin2dec': bin2dec xs = ""
|
47 | bin2dec xs = ""
| ^^
traceProcP1.hs:48:31: error:
* Couldn't match expected type `Int' with actual type `Char'
* In the second argument of `(+)', namely `2 ^ (length xs) * x'
In the expression: bin2dec xs + 2 ^ (length xs) * x
In an equation for `bin2dec':
bin2dec (x : xs) = bin2dec xs + 2 ^ (length xs) * x
|
48 | bin2dec (x:xs) = bin2dec xs + 2^(length xs) * x
| ^^^^^^^^^^^^^^^^^^
I know this has to do with changing the datatypes, but I am having trouble type casting in Haskell. I have tried type casting x with read and I have tried making guards that will turn the '0' into 0 and '1' into 1, but I am having trouble getting these to work. Any help would be very appreciated.
There is no casting. If you want to convert from one type to another, there needs to be a function with the right type signature to do so. When looking for any function in Haskell, Hoogle is often a good start. In this case, you're looking for Char -> Int, which has several promising options. The first one I see is digitToInt, which sounds about right for you.
But if you'd rather do it yourself, it's quite easy to write a function with the desired behavior, using pattern matching:
bit :: Char -> Int
bit '0' = 0
bit '1' = 1
bit c = error $ "Invalid digit '" ++ [c] ++ "'"

What's wrong with this recursive curried function

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.

Function with more arguments and integration

I have I simple problem but I cannot find a solution anywhere.
I have to integrate a function (for example using a Simpson's rule subroutine) but I am obliged to pass to my function more than one argument: one is the variable that I want to integrate later and another one is just a value coming from a different calculation which I cannot perform inside the function.
The problem is that the Simpson subroutine only accept f(x) to perform the integral and not f(x,y).
After Vladimir suggestions I modified the code.
Below the example:
Program main2
!------------------------------------------------------------------
! Integration of a function using Simpson rule
! with doubling number of intervals
!------------------------------------------------------------------
! to compile:
! gfortran main2.f90 -o simp2
implicit none
double precision r, rb, rmin, rmax, rstep, integral, eps
double precision F_int
integer nint, i, rbins
double precision t
rbins = 4
rmin = 0.0
rmax = 4.0
rstep = (rmax-rmin)/rbins
rb = rmin
eps = 1.0e-8
func = 0.0
t=2.0
do i=1,rbins
call func(rb,t,res)
write(*,*)'r, f(rb) (in main) = ', rb, res
!test = F_int(rb)
!write(*,*)'test F_int (in loop) = ', test
call simpson2(F_int(rb),rmin,rb,eps,integral,nint)
write(*,*)'r, integral = ', rb, integral
rb = rb+rstep
end do
end program main2
subroutine func(x,y,res)
!----------------------------------------
! Real Function
!----------------------------------------
implicit none
double precision res
double precision, intent(in) :: x
double precision y
res = 2.0*x + y
write(*,*)'f(x,y) (in func) = ',res
return
end subroutine func
function F_int(x)
!Function to integrate
implicit none
double precision F_int, res
double precision, intent(in) :: x
double precision y
call func(x,y,res)
F_int = res
end function F_int
Subroutine simpson2(f,a,b,eps,integral,nint)
!==========================================================
! Integration of f(x) on [a,b]
! Method: Simpson rule with doubling number of intervals
! till error = coeff*|I_n - I_2n| < eps
! written by: Alex Godunov (October 2009)
!----------------------------------------------------------
! IN:
! f - Function to integrate (supplied by a user)
! a - Lower limit of integration
! b - Upper limit of integration
! eps - tolerance
! OUT:
! integral - Result of integration
! nint - number of intervals to achieve accuracy
!==========================================================
implicit none
double precision f, a, b, eps, integral
double precision sn, s2n, h, x
integer nint
double precision, parameter :: coeff = 1.0/15.0 ! error estimate coeff
integer, parameter :: nmax=1048576 ! max number of intervals
integer n, i
! evaluate integral for 2 intervals (three points)
h = (b-a)/2.0
sn = (1.0/3.0)*h*(f(a)+4.0*f(a+h)+f(b))
write(*,*)'a, b, h, sn (in simp) = ', a, b, h, sn
! loop over number of intervals (starting from 4 intervals)
n=4
do while (n <= nmax)
s2n = 0.0
h = (b-a)/dfloat(n)
do i=2, n-2, 2
x = a+dfloat(i)*h
s2n = s2n + 2.0*f(x) + 4.0*f(x+h)
end do
s2n = (s2n + f(a) + f(b) + 4.0*f(a+h))*h/3.0
if(coeff*abs(s2n-sn) <= eps) then
integral = s2n + coeff*(s2n-sn)
nint = n
exit
end if
sn = s2n
n = n*2
end do
return
end subroutine simpson2
I think I'm pretty close to the solution but I cannot figure it out...
If I call simpson2(F_int, ..) without putting the argument in F_int I receive this message:
call simpson2(F_int,rmin,rb,eps,integral,nint)
1
Warning: Expected a procedure for argument 'f' at (1)
Any help?
Thanks in advance!
Now you have a code we can work with, good job!
You need to tell the compiler, that F_int is a function. That can be done by
external F_int
but it is much better to learn Fortran 90 and use modules or at least interface blocks.
module my_functions
implicit none
contains
subroutine func(x,y,res)
!----------------------------------------
! Real Function
!----------------------------------------
implicit none
double precision res
double precision, intent(in) :: x
double precision y
res = 2.0*x + y
write(*,*)'f(x,y) (in func) = ',res
return
end subroutine func
function F_int(x)
!Function to integrate
implicit none
double precision F_int, res
double precision, intent(in) :: x
double precision y
call func(x,y,res)
F_int = res
end function F_int
end module
Now you can easily use the module and integrate the function
use my_functions
call simpson2(F_int,rmin,rb,eps,integral,nint)
But you will find that F_int still does not know what y is! It has it's own y with undefined value! You should put y into the module instead so that everyone can see it.
module my_functions
implicit none
double precision :: y
contains
Don't forget to remove all other declarations of y! Both in function F_int and in the main program. Probably it is also better to call it differently.
Don't forget to set the value of y somewhere inside your main loop!

Is it possible to use functions in Haskell parameters?

I have seen a few examples of Haskell code that use functions in parameters, but I can never get it to work for me.
example:
-- Compute the nth number of the Fibonacci Sequence
fib 0 = 1
fib 1 = 1
fib (n + 2) = fib (n + 1) + fib n
When I try this, it I get this error:
Parse error in pattern: n + 2
Is this just a bad example? Or do I have to do something special to make this work?
What you have seen is a special type of pattern matching called "n+k pattern", which was removed from Haskell 2010. See What are "n+k patterns" and why are they banned from Haskell 2010? and http://hackage.haskell.org/trac/haskell-prime/wiki/RemoveNPlusK
As Thomas mentioned, you can use View Patterns to accomplish this:
{-# LANGUAGE ViewPatterns #-}
fib 0 = 1
fib 1 = 1
fib ((subtract 2) -> n) = fib (n + 1) + fib n
Due to the ambiguity of - in this case, you'll need to use the subtract function instead.
I'll try to help out, being a total newbie in Haskell.
I believe that the problem is that you can't match (n + 2).
From a logical viewpoint, any argument "n" will never match "n+2", so your third rule would never be selected for evaluation.
You can either rewrite it, like Michael said, to:
fib n = fib (n - 1) + fib (n - 2)
or define the whole fibonnaci in a function using guards, something like:
fibonacci :: Integer -> Integer
fibonacci n
| n == 0 = 0
| (n == 1 || n == 2) = 1
| otherwise = fibonacci(n-1) + fibonacci(n-2)
The pattern matcher is limited to constructor functions. So while you can match the arguments of functions like (:) (the list constrcutor) or Left and Right (constructors of Either), you can't match arithmetic expressions.
I think the fib (n+2) = ... notation doesn't work and is a syntax error. You can use "regular expression" style matching for paramters, like lists or tuples:
foo (x:xs) = ...
where x is the head of the list and xs the remainder of the list or
foo (x:[]) =
which is matched if the list only has one element left and that is stored in x. Even complex matches like
foo ((n,(x:xs)):rg) = ...
are possible. Function definitions in haskell is a complex theme and there are a lot of different styles which can be used.
Another possibility is the use of a "switch-case" scheme:
foo f x | (f x) = [x]
foo _ _ = []
In this case, the element "x" is wrapped in a list if the condition (f x) is true. In the other cases, the f and x parameters aren't interesting and an empty list is returned.
To fix your problem, I don't think any of these are applicable, but why don't throw in a catch-remaining-parameter-values function definition, like:
fib n = (fib (n - 1)) + (fib (n - 2))
Hope this helps,
Oliver
Since (+) is a function, you can't pattern match against it. To do what you wanted, you'd need to modify the third line to read: fib n = fib (n - 1) + fib (n - 2).

OCaml: Using a comparison operator passed into a function

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