Composition using foldr SML - sml

Is there any way to do something like a(b(c(5))) from a variable that contains the functions?
The code would be something like that:
val a = fn x => x + 10
val b = fn x => x * x
val c = fn x => (x - 2) * 3
val fs = [a, b, c]

You can apply op to the composition operator o so that it can be used as a function, and then use that function with foldr to fold the list of functions down to a single function. Use the identity function as an initial value.
Thus, foldr (op o) identity [a, b, c] is equivalent to a o (b o (c o identity)), where identity is the identity function:
fun identity x = x;
Using the posted definitions for a, b, c, and fs it's not too bad to write OP example as a one-liner:
- (foldr (op o) (fn x => x) fs) 5;
val it = 91 : int
- a(b(c 5));
val it = 91 : int
It's a bit easier if identity has been defined, but even nicer to define a higher-order function to abstract this away:
fun composeList fs = foldr (op o) (fn x => x) fs;
- composeList fs 5;
val it = 91 : int

Related

Converting int to real in SML

Newbie at SML
I have the following code that returns the absolute value of a list. I need it to be of type int list -> real list. Where do I place the statement that converts it to real while constraining this code to a single line?
val myabs = map(fn x => if x >= 0 then x else ~x) [1,~2, 3, ~4];
You convert an int to real using Real.fromInt:
- Real.fromInt 42;
> val it = 42.0 : real
You can convert an int list into a real list by List.map Real.fromInt:
- List.map Real.fromInt [1, 2, 3];
> val it = [1.0, 2.0, 3.0] : real list
You can convert an integer to its absolute using Int.abs:
- Int.abs ~42;
> val it = 42 : int
You can combine those two functions and so both convert an integer to its absolute and convert it to real:
- (Real.fromInt o Int.abs) ~42;
> val it = 42.0 : real
And you can do this for an entire list using List.map (Real.fromInt o Int.abs):
- List.map (Real.fromInt o Int.abs) [~1, ~2, ~3];
> val it = [1.0, 2.0, 3.0] : real list
You can express that as a single function:
fun myabs xs = List.map (fn x => Real.fromInt (Int.abs x)) xs
And you can shorten this function a bit:
val myabs = List.map (fn x => Real.fromInt (Int.abs x))
val myabs = List.map (fn x => (Real.fromInt o Int.abs) x)
val myabs = List.map (Real.fromInt o Int.abs)
So the only missing pieces were:
Instead of if x >= 0 then x else ~x, use Int.abs x.
To convert x to real, use Real.fromInt x.
To apply multiple functions in sequence, f (g x) or (f o g) x, like math.

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)]

ML currying and anonymous functions

Could someone please explain to me what is going on in these three bindings?
What is the significance of the parens? What is the meaning of g and why does it have to be a g as an argument in the anonymous function? And overall what is actually happening in all of this... Thank you!
val a = fn g => (fn x => fn y => x) (g 0) (g 7);
val b = fn g => (fn x => fn y => x) (g 0) (g "happy");
val c = fn g => (fn x => fn y => x) (g 0) (g (g 7));
The function (fn x => fn y => x) is the constant function. It takes two arguments (x and y) and always returns the first argument (i.e. x).
This function is applied to two arguments in all three functions a, b and c:
In a the constant function is applied to (g 0) and (g 7).
In b the constant function is applied to (g 0) and (g "happy").
In c the constant function is applied to (g 0) and (g (g 7)).
In all three cases, the result is (g 0) because the second argument is discarded. Therefore, all the three functions can be simplified to:
val a = fn g => g 0
val b = fn g => g 0
val c = fn g => g 0
Actually, the second function (i.e. b) raises a type error because g is first applied to an int and later applied to a string.
Although the functions a and c have the same result yet they do not have the same type:
The type of a is (int -> 'a) -> 'a because we don't know the return type of the function g. Hence, it is a polymorphic function and it's more general than c.
The type of c is (int -> int) -> int because g is applied to its own result (i.e. g is applied to (g 7)). Hence, its return type must be the same as its argument type (i.e. int).
Therefore, a is more general than c and every instance of c can be safely replaced with a but not vice versa.

What does function return when "function times zero" in functional programming?

I am stuck with this SML assignment. I am trying to create a compound function (fun compound n f). It's supposed to apply the function f on itself for n times for example, compound 3 f will equal to f(f(f(x))). I got it to work except for case where n is zero. I asked the professor but he won't tell me a direct answer. He tried to give me an hint that "what's function times zero?" I still can't figure that out either. Can stackoverflow figure it out?
Thanks.
My code:
fun compound n f =
if n < 2 then
if n = 0 then fn x => f x else fn x => f x
else fn x => f(compound (n-1) f(x));
example:
val fnc = fn x => x + 1; (* example function to be used *)
compound 5 fnc(10); (* will return 15 which is correct*)
compound 0 fnc(10); (* returns 11, should be 10 *)
Answer:
fun compound n f =
if n < 2 then
if n = 0 then fn x => x else fn x => f x
else fn x => f(compound (n-1) f(x));
I won't give you the final answer because I don't like to upset teachers ;) However, I'll try a derivation that I believe you'll find easy to complete.
Let's start from a very simple case. Let's "reimplement" function application, i.e., let's write a function that takes a function and an argument and apply the first param to the second one:
fun apply f a = f a
Let's use a contrived function, that increments integers, for testing:
- fun inc n = n + 1;
val inc = fn : int -> int
- inc 1;
val it = 2 : int
- apply inc 1;
val it = 2 : int
Now, let's write apply2, a function which takes a function and an argument and applies the param function two times to the argument:
fun apply2 f a = f (f a)
Let's test it with inc:
- apply2 inc 1;
val it = 3 : int
Seems to be working. As you might expect, we'd now implement apply3, apply4 and so on. Let's see some of them at once:
fun apply f a = f a
fun apply2 f a = f (f a)
fun apply3 f a = f (f (f a))
fun apply4 f a = f (f (f (f a)))
It looks like we can rewrite later ones in terms of the earlier ones:
fun apply2 f a = f (apply f a)
fun apply3 f a = f (apply2 f a)
fun apply4 f a = f (apply3 f a)
We can even rewrite apply:
fun apply f a = f (apply0 f a)
Remember the previous definition of apply, they're equivalent:
fun apply f a = f a
So, what should apply0 be?
fun apply0 f a = ...
What is the base case for this algorithm? i.e. at what value of n does the recursion terminate? When it terminated what do you return? Think about what you would want to return if f is not applied to x. In the context of your example, if fnc is applied to 10 zero times, what should be returned?
fun compound n f =
(* If n equals the termination value, then return the base case*)
if n = ?
else fn x => f(compound (n-1) f(x));
There is a pattern here that exists in the base case for recursive algorithms. For example, what is the sum of a list with no elements? Or, what is the length of a list with no elements?

ml datatype (with primitive functions) how to make?

i have this datatype
datatype e = X | Const of int | P of e*e | S of e*e | M of e*e | D of e*e;
and this procedure
val rec evl = fn (Const k)=>(fn x=>k)| X=> (fn x=>x)| P(e1,e2)=> (fn x=> (evl e1 x)+(evl e2 x))| S(e1,e2)=> (fn x=> (evl e1 x)-(evl e2 x))| M(e1,e2)=> (fn x=> (evl e1 x)*(evl e2 x))| D(e1,e2)=> (fn x=> (evl e1 x)/(evl e2 x));
how to expand this datatype and evl procedure to do:
-val addsub = evl( A( X(1),X(2),X(3), S( X(4),X(5) ) )) ;
addsub(4,5,2,9,8) return it = 12 (4+5+2+(9-8))
P = +, S = -, M = * , D = /
and not just for X(5), I need for X(n)...?
Some notes about your datatype and function:
X is a redundant case, it has no
meaning in context of arithmetic
expression.
You overused lamda functions, it
makes your code so hard to
understand.
S (subtract) and D (divide) are not commutative, it is a bad idea to do those operations on a list of arguments. I demonstrate how to do so with P (Plus) and M (Multiply):
datatype e2 = Const of int | P of e2 list | M of e2 list;
val rec evl2 =
fn Const k => k
| P es => List.foldl (fn (e, acc) => acc + (evl2 e)) 0 es
| M es => List.foldl (fn (e, acc) => acc * (evl2 e)) 1 es;
For example: evl2 (P [Const 3, Const 2, M [Const 3, Const 2, Const 1]]) would return 11.
If you still want to do it with S and D, you can infer from the above code fragment.