How can I divide two numbers in ML defined as a datatype? - sml

I'm trying to write a recursive function in SML that receives two natural numbers n1,n2 and returns the result of n1 div n2
The datatype natural is defined as follows:
datatype natural = zero | Succ of natural
I want to write it in terms of the new datatype , or in other words, not by converting them to their regular form and converting back the result.
Any ideas how division is done in this definition?

You could start by defining subtraction:
exception Negative
fun sub (a, zero) = a
| sub (zero, b) = raise Negative
| sub (Succ a, Succ b) = sub (a, b)
From here, it should be pretty easy to simply count how many times you can subtract n2 from n1 without going negative. In particular, this equation should help:
n1 div n2 = 1 + (n1 - n2) div n2
I'll leave the rest to you.

Similar to Sam Westrick's definition, "number of times you can subtract n2 from n1 without going negative", you could also do integer division with addition and greater-than using the definition, "number of times you can add n2 to itself before it is greater than n1."
datatype nat = Z | S of nat
fun gt (S x, S y) = gt (x, y)
| gt (S _, Z) = true
| gt (Z, _) = false
fun add (x, Z) = x
| add (x, S y) = add (S x, y)
fun divide (_, Z) = raise Domain
| divide (x, y) = (* ... *)
Addition might seem like a conceptually simpler thing than subtraction. But greater-than is a more expensive operator than determining when a number is negative, since the case is incurred by induction, so Sam's suggestion would be more efficient.
You might test your solution with the following tests:
fun int2nat 0 = Z
| int2nat n = S (int2nat (n-1))
fun nat2int Z = 0
| nat2int (S n) = 1 + nat2int n
fun range (x, y) f = List.tabulate (y - x + 1, fn i => f (i + x))
fun divide_test () =
let fun showFailure (x, y, expected, actual) =
Int.toString x ^ " div " ^ Int.toString y ^ " = " ^
Int.toString expected ^ ", but divide returns " ^
Int.toString actual
in List.mapPartial (Option.map showFailure) (
List.concat (
range (0, 100) (fn x =>
range (1, 100) (fn y =>
let val expected = x div y
val actual = nat2int (divide (int2nat x, int2nat y))
in if expected <> actual
then SOME (x, y, expected, actual)
else NONE
end))))
end

Related

Return list of tuples given a positive integer using recursion on Haskell

I am trying to define a "pairs" function, which given a positive integer, returns a list of pairs of positive integers, with the first component of the pair less than or equal to the second component, the sum of which is equal to the given positive integer. For example:
pairs 7 = [(1,6),(2,5),(3,4)]
pairs 10 = [(1,9),(2,8),(3,7),(4,6),(5,5)]
I've managed to do this without using recursion:
pairs :: Integral a => a -> [(a, a)]
pairs 1 = []
pairs x
| x <= 0 = error "It is not positive"
| mod x 2 == 0 = zip (enumFromTo 1 (div x 2)) (enumFromThenTo (pred x) (pred(pred x)) (div x 2))
| otherwise = zip (enumFromTo 1 (div x 2)) (enumFromThenTo (pred x) (pred(pred x)) (succ(div x 2)))
And using recursion:
generateTupleList:: Integral a => [(a, a)] -> [(a, a)]
generateTupleList[] = undefined
generateTupleList((a,b):[])
| (a + 1) > (b - 1) = ((a,b):[])
| otherwise = [(a,b)] ++ generateTupleList(((a+1),(b-1)):[])
pairs:: Integral a => a -> [(a, a)]
pairs 1 = []
pairs x
| x <= 0 = error "It is not positive"
| otherwise = generateTupleList[(1,x-1)]
My question is the following, Is there any other way of doing this "pairs" function using recursion and without creating another sub-function (generateTupleList in my case)?
You could just do this:
pairs :: Integral a => a -> [(a, a)]
pairs x = map (\y -> (y, x - y)) [1..x `div` 2]
In case you don't know, [a..b] is equivalent to enumFromThenTo a b, and wrapping a function in backticks makes it behave like an operator, so a `div` b is the same as div a b.

Haskell infinite recursion in list comprehension

I am trying to define a function that accepts a point (x,y) as input, and returns an infinite list corresponding to recursively calling
P = (u^2 − v^2 + x, 2uv + y)
The initial values of u and v are both 0.
The first call would be
P = (0^2 - 0^2 + 1, 2(0)(0) + 2) = (1,2)
Then that resulting tuple (1,2) would be the next values for u and v, so then it would be
P = (1^2 - 2^2 + 1, 2(1)(2) + 2) = (-2,6)
and so on.
I'm trying to figure out how to code this in Haskell. This is what I have so far:
o :: Num a =>(a,a) -> [(a,a)]
o (x,y) = [(a,b)| (a,b)<- [p(x,y)(x,y)]]
where p(x,y)(u,v) = ((u^2)-(v^2)+x,(2*u*v)+y)
I'm really not sure how to make this work. Any help would be appreciated!
Let's first ignore the exact question you have, and focus on getting the loop working. What you want, essentially, is to have something that takes some initial value iv (namely, (0, 0) for (u, v)), and returns the list
f iv : f (f iv) : f (f (f iv)) : f (f (f (f iv))) : ...
for some function f (constructed from your p and (x, y)). Moreover, you want the result to reuse the previously computed elements of the list. If I would write a function myself that does this, it might looke like this (but maybe with some different names):
looper :: (a -> a) -> a -> [a]
looper f iv = one_result : more_results
where
one_result = f iv
more_results = looper f one_result
But, of course, I would first look if a function with that type exists. It does: it's called Data.List.iterate. The only thing it does wrong is the first element of the list will be iv, but that can be easily fixed by using tail (which is fine here: as long as your iteration function terminates, iterate will always generate an infinite list).
Let's now get back to your case. We established that it'll generally look like this:
o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate f iv)
where
f (u, v) = undefined
iv = undefined
As you indicated, the initial value of (u, v) is (0, 0), so that's what our definition of iv will be. f now has to call p with the (x, y) from o's argument and the (u, v) for that iteration:
o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate f iv)
where
f (u, v) = p (x, y) (u, v)
iv = (0, 0)
p = undefined
It's as simple as that: the (x, y) from o's definition is actually in scope in the where-clause. You could even decide to merge f and p, and end up with
o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate p iv)
where
iv = (0, 0)
p (u, v) = (u^2 - v^2 + x, 2 * u * v + y)
Also, may I suggest that you use Data.Complex for your application? This makes the constraints on a a bit stricter (you need RealFloat a, because of Num.signum), but in my opinion, it makes your code much easier to read:
import Data.Complex
import Data.List (iterate)
{- ... -}
o :: Num (Complex a) => Complex a -> [Complex a]
o c = tail (iterate p iv)
where
iv = 0 -- or "0 :+ 0", if you want to be explicit
p z = z^2 + c
You want:
To construct a list [(u, v)] with the head of this list equal (0, 0)
And then map this list with the function \(u, v) -> (u^2 - v^2 + x, 2 * u * v + y), appending results of this function to the list.
We can write this function as described:
func :: (Num t) => (t, t) -> [(t, t)]
func (x, y) = (0, 0) : map functionP (func (x, y))
where functionP (u, v) = (u^2 - v^2 + x, 2 * u * v + y)
GHCi > take 5 $ func (1, 2)
> [(0,0),(1,2),(-2,6),(-31,-22),(478,1366)]

Using FOIL in SML

I'm writing a small program that takes coefficients of two polynomials and FOILs them together, however I can only seem to multiply elements at the same indices.
fun polyMult([],[]) = []
| polyMult(M, []) = []
| polyMult([], N) = []
| polyMult(M as x::xs, N as y::ys) =
(x * y) :: polyMult(M, ys);
I can successfully multiply the first element of M by every element of N, but then afterwards I want to be able to advance one element in M and then take that and multiply it by every element in N.
Is there any way I can advance the index in M and repeat the multiplication process? I.E
polyMult(tl(M) as x::xs, N as y::ys) =
(x * y) :: polyMult(M, ys);
Something along these lines
fun foldL F y nil = y
| foldL F y (x::xr) = foldL F (F(x,y)) xr;
fun polymult(M, nil) = nil
| polymult(nil, N) = nil
| polymult(m::mr, N) = foldL(fn(x,a) => x * a) m N::polymult(mr,N);
But you will need to figure out how to make it only accept real numbers and not integers as it does now ;)

number_in_month exercise (Count elements in a list)

I have been trying to count elements in a list of integer 3-tuples, that equals a given integer using SML, but it's not working. Can anyone help me figure out what's wrong with the below code or straighten it up for me?
fun number_in_month(x : int*int*int list, m: int) =
if null x then 0
else
let fun inc x = x + 1;
in
val counter = 0;
if m = #2 (hd x) andalso m > 0 then inc counter
number_in_month((tl x), m)
` else
number_in_month((tl x), m)
end
This function is supposed to return the number of times m equals to the second element of each tuple in the list.
Clearly you have a hard time to let go of your imperative thinking.
Let me try and address some of your issues
You should be using pattern matching instead of using null x, hd x and tl x.
This also apply to decomposing tuples and records. For example
fun number_in_month ((x1, x2, x3) :: xs, m) = ...
or, since we don't ever use x1 and x3
fun number_in_month ((_, x2, _) :: xs, m) = ...
This way it is clearly seen that the first argument is a list of 3-tuples, and no type annotation
is needed
Also when you omit the explicit type annotation, which is the whole idea of having a type system
that can infer them for you (see next point), then this code
fun foo42 xs = map (fn x => #2 x) xs
will give you some nasty errors on "unresolved flex record" (this error message is from SML/NJ)
/tmp/sml20620PlF:105.5-105.44 Error: unresolved flex record
(can't tell what fields there are besides #2)
which is easily fixed by decomposing the 3-tuple
fun foo42 xs = map (fn (_, x2, _) => x2) xs
Speaking of type annotations. They are (almost always) not needed, and they clutter up the
readability of the code. Not to mention that they unnecessarily restricts the types you function
may be used on.
Also the type annotation you have given is erroneous according to what you really wan't. You
should have places parenthesis around the int * int * int. Currently it is interpreted as a
3-tuple of two ints and an int list int * int * (int list).
If you really insist in type annotating your function, then you can do it like this
val number_in_month : (int * int * int) list * int -> int =
fn ([] , m) => 0
| ((_,x2,_) :: xs, m) => 42
This is "almost" like Haskell, where the type is given just before the function declaration.
Try to be more consistent in they way you indent your code. That will give you better clarity.
Here I'm specifically thinking of the way you have indented the else part end the in ... end
part. The below part is clearly still erroneous in so many ways i can't begin to imagine, but it
gives an idea as how to do it
fun number_in_month(x : int*int*int list, m: int) =
if null x then 0
else
let fun inc x = x + 1;
in
val counter = 0;
if m = #2 (hd x) andalso m > 0 then
inc counter
number_in_month((tl x), m)
else
number_in_month((tl x), m)
end
You can't declare a variable val counter = 0 inside the in ... end part of a let-expression.
The semantics of a let-expression is
let
dec
in
exp_1; ...; exp_n
end
thus all declarations (function and value bindings, etc) must go in the let ... in part.
There is no need on earth to have an increment function, it just clutters the readability.
Remember that SML uses single assignment, thus variables are immutable after they are declared.
The sequence-thing inside your nested if-expression
inc counter
number_in_month((tl x), m)
makes absolutely no sense. The only way you can have more than one expression inside the
then ... else part (actually any place, where a single expression is expected), is with a
sequence (exp_1; ...; exp_n). However this is only usable when all but the last expression has
side effect(s), as their results is ignored/thrown away
- (print "Foo\n"; print "Bar\n"; 42);
Foo
Bar
val it = 42 : int
If you search a bit here on SO, you will see that a quite similar question has recently been asked and answered. Though it differs in the the type of the last argument, you might still get some useful pointers.
All in all a solution might look like
fun number_in_month ([], _) = 0
| number_in_month ((_,x2,_) :: xs, m) =
if x2 = m then
1 + number_in_month(xs, m)
else
number_in_month(xs, m)
However since your problem is simpler than the previously stated one, you could easily use some of the higher-order functions from the list module in the basis library
fun number_in_month (xs, m) = length (List.filter (fn (_, x2, _) => x2 = m) xs)
Or even (arguably) simpler, by folding over the list and incrementing a variable along the way each time it matches
fun number_in_month (xs, m) = foldl (fn ((_, x2, _), b) => if x2 = m then b+1 else b) 0 xs
fun number_in_month (L : (int*int*int) list, m : int) =
if L = nil
then 0
else
(if #2 (hd L) = m then 1 else 0) + number_in_month (tl L,m);
TESTING:
number_in_month ([] , 2);
number_in_month ([(1,2,3)] , 2);
number_in_month ([(1,2,3),(2,2,2)] , 2);
number_in_month ([(1,2,3),(2,2,2),(19,11,29)] , 2);
number_in_month ([(1,2,3),(2,2,2),(19,11,29),(10,28,19)] , 2);
number_in_month ([(1,2,3),(2,2,2),(19,11,29),(10,2,19)] , 2);
number_in_month ([(1,2,3),(2,2,2),(19,11,29),(10,28,19)] , 2);
number_in_month ([(1,2,3),(2,2,2),(19,11,29),(10,28,19)] , 2);
number_in_month ([(1,2,3),(2,2,2),(19,11,29),(10,28,19),(16,2,7)] , 2);
Reference:
http://www.cs.sunysb.edu/~leo/CSE215/smllistexamples.txt
http://www.standardml.org/Basis/list.html

Implementing a counter in SML

I am trying to solve a polynomial evaluation problem on SML, here is the current code I have:
fun eval (nil, b:real) = 0.0
| eval(x::xs, a:real) =
let val y:real = 0.0
fun inc z:real = z+1.0;
in
(x*Math.pow(a,(inc y))) + eval(xs,a)
end;
The problem with this is that it only increments y once, is there a way to have y start at 0 and keep increasing by 1 with every recursion?
You can do that by using the concept of local function (or helper functions). Here's the code :
local
fun helper(nil,b:real,_)=0.0
|helper(x::xt,b:real,y)=(x*(Math.pow(b,(y)))) + helper(xt,b:real,y+1.0)
in
fun eval(x,a:real)= helper(x,a,0.0)
end
I Hope this can solve your problem :)
y is set to be 0 in the let expression inside your function, so every time you call that function it has the value 0. If you want to have a different value for y for different calls to the eval function then you should make it a parameter of that function.
If the xs are supposed to be coefficients in increasing order:
fun eval'( nil, a, n) = 0.0
| eval'(x::xs, a, n) = x*Math.pow(a, n) + eval'(xs, a, n + 1.0)
fun eval(xs, a) = eval'(xs, a, 0.0)
Or, since a is actually constant across the recursion:
fun eval(xs, a) =
let
fun eval'( nil, n) = 0.0
| eval'(x::xs, n) = x*Math.pow(a, n) + eval'(xs, n + 1.0)
in
eval'(xs, 0.0)
end
Or if you don't want to write the recursion youself:
fun eval(xs, a) = foldl (fn(x, (s, n)) => (x*Math.pow(a, n) + s, n + 1.0)) (0.0, 0.0) xs