Using foldr to simplify a function (SML / NJ) - functional-programming

I have this function
fun exist p M = foldr( fn(x,y) => x orelse y ) false (map p M)
I need to write it using only the foldr function, but can only call foldr once. I'm confused on how I should handle this. Do i need to revise my anon function?

Yes, you need to revise your anonymous function. You can call p inside it.
fun exist p M = foldr (fn (x, y) => y orelse (p x)) false M
map in your code transforms values to bool type. You can do that in anonymous function. Also, switching x and y in orelse will save you some machine time, since if value satisfying p was found, p won't be executed on the rest of M.
- fun exist p M = foldr (fn (x, y) => y orelse (p x)) false M;
val exist = fn : ('a -> bool) -> 'a list -> bool
- exist (fn e => e = 1) [2,3,4];
val it = false : bool
- exist (fn e => e = 1) [2,3,4,1,2,3,4];
val it = true : bool
foldr takes 3 arguments
function to fold list. It takes tuple argument (x, y), where x is current value from list, y - value list have been folded to so far.
Starting value. It will be passed as y to the first first argument function together with the last value of a list.
List to fold. Each value (starting last) of this list will be passed to the first argument function as x.
foldr will call folding function for every element of passed list.
Calls to folding (called it anon here) function for exist (fn e => e = 1) [2,1,4]; call:
anon (4, false); // here `false` is the false passed to `foldr`; returns false
anon (1, false orelse (p 4)); // (p 1) -> true; returns true
anon (2, (false orelse (p 4)) orelse (p 1)); // returns true becuase `true or (p 2)` is true

Related

Haskell: How can I implement an applicative functor on own map data type?

I am very new to Haskell and I wrote a Data Type in Haskell
for representing an interval map.
What does that mean? Briefly: A map data type that gives you a value back
for every possible key (put simply in my case [0..]).
Then you insert "sequences" like I want my map to hold from 7 to 23 'b'
so keys 0 to 6 will be init value e.g. 'a' and 7 to 23 will be 'b' and 24 and ongoing will be 'a' again etc.
I managed to wrote the Data Type, a get and insert function as well as a
functor version.
But I can't managed to get a applicative functor version to work.
The idea is to set the keys value to [0..] and just work on the values.
Here is my code and thanks for any provided help!
-- Building an interval map data structure in haskell
data IntervalMap k v = IntervalMap {keys :: [k] , values :: [v]} | Empty deriving Show
-- k = key, Typ variable
-- v = value, Typ variable
singleton :: (Enum k, Num k) => v -> IntervalMap k v
singleton v = IntervalMap{keys=[0..], values= repeat v}
-- get operator => a ! 5 = value at position 5
(!) :: Ord k => IntervalMap k v -> k -> v
(!) iMap k = snd (head (filter (\(x, y) -> x == k) (zip (keys iMap) (values iMap)) ))
-- insert a sequence into intervalMap
insert :: (Ord k, Num k, Enum k) => k -> k -> v -> IntervalMap k v -> IntervalMap k v
insert start end value iMap = IntervalMap {keys=keys iMap, values = rangeChanger (values iMap) start end value}
-- helper function to change a range of values in an intervalMap
rangeChanger :: (Num a1, Enum a1, Ord a1) => [a2] -> a1 -> a1 -> a2 -> [a2]
rangeChanger iMapValues start end value = [if (i >= start) && (i <= end) then newValue else iMapValue | (iMapValue, newValue, i) <- zip3 iMapValues (repeat value) [0..]]
-- functor instance for intervalMap
instance Functor (IntervalMap k) where
-- fmap :: (a -> b) -> f a -> f b
fmap f iMap = IntervalMap {keys=keys iMap, values= map f (values iMap) }
-- applicative functor for intervalMap
instance (Ord k, Num k, Enum k) => Applicative (IntervalMap k) where
pure k = IntervalMap{keys=[0..], values=repeat k}
_ <*> Nothing = Nothing
-- HOW TO DO?
-- class Functor functor => Applicative functor where
-- pure :: a -> functor a
-- (<*>) :: functor (a -> b) -> functor a -> functor b
-- (*>) :: functor a -> functor b -> functor b
-- (<*) :: functor a -> functor b -> functor a
It seems like you always expect the keys to be [0..], e.g. it is hard-coded in your rangeChanger function. If that is the case then it is redundant and honestly I would leave it out. You can easily reconstruct it by doing something like zip [0..] (values iMap) as you do in the rangeChanger function.
If you make that change, then your IntervalMap data structure is basically the same as ZipList which has an applicative instance here:
instance Applicative ZipList where
pure x = ZipList (repeat x)
liftA2 f (ZipList xs) (ZipList ys) = ZipList (zipWith f xs ys)
You see that this doesn't define a <*> but that can be defined in terms of liftA2: p <*> q = liftA2 (\f x -> f x) p q, so you could also write that explicitly for ZipList:
ZipList fs <*> ZipList xs = ZipList (zipWith (\f x -> f x) fs xs)
Edit: I should also mention that one difference with ZipList is that you have an Empty constructor for your IntervalMap type. That makes things harder, you would need to know that your values have some sort of default value, but that is not possible in general (not every type has a default value), so your type cannot be an Applicative. Do you really need that Empty case?

OCaml apply anonymous function without argument n-times?

How would I go about applying a function n-times in OCaml if I don't
know the functions argument?
I want the call iter(n, fun x -> 2+x) 0 to evaluate to 2*n since
that would be the same as 2+2+2+2.... Also, if n=0 it should
return the identity function.
My attempt:
let rec iter : int * (int -> int) -> (int -> int)
= fun (n,f) ->
if n = 0 then f
else iter((n-1), f( f () ))
Possible duplicate: OCaml recursive function to apply a function n times but this question has an argument for the anonymous function so the answers does not help me.
You may not “have an argument” right now, but since the result is a function you can always just bring an argument in scope by returning a lambda:
let rec iter : int * (int -> int) -> (int -> int)
= fun (n,f) ->
if n = 0 then f
else fun x -> iter(n-1, f) (f x);;
Try it online!
Note that, as Willem remarks, your base case is probably wrong: for n=0, you want to return the identity function regardless of what function is passed in. Otherwise you get strange behaviour, for instance such a function should generally fulfill iter (n, fun x -> x+1) 0 ≡ n, but with your base case it gives n+1.
I would write the function thus:
let rec iter : int -> ('a -> 'a) -> ('a -> 'a)
= fun n f x -> if n = 0
then x
else iter (n-1) f (f x);;
Try it online!
Here I've not explicitly mentioned the identity function, but because I just return x when n is zero, that's what the identity function does. Alternatively, you can return another lambda which just passes the argument through:
let rec iter : int -> ('a -> 'a) -> 'a -> 'a
= fun n f ->
if n = 0
then fun x -> x (* identity function *)
else fun x -> iter (n-1) f (f x);;
I am not really sure if this is what you want - a small modification of the answer you linked to seems to do the job though:
*Edit: identity function depends on the nature of the function you pass to iter (right?), so I am not really sure how you can get it just from looking at f. That's why I am only returning f for now. And repeat fun x -> x + 2 n times - wouldn't that give you x + 2 * n?
let iter n f =
let chain_func f1 f2 arg = f1 (f2 arg) in
let rec aux n f newf =
if n <= 0 then newf else aux (n - 1) f ( chain_func f newf ) in
aux (n - 1) f f;;
*Edit 2: identity function is fun x -> x so the last line needs to be fixed to: aux n f (fun x -> x)

foldr/foldl with logic operators in SML

I'm trying to build a function in SML using foldr or foldl that will return the logic or and logic and of all elements in a list.
I've tried in this way, using and and or:
fun band x = foldr (op and) true x;
fun bor x = foldr (op or) false x;
And also using andalso and orelse. But I keep receiving error messages such as:
Error: unbound variable or constructor: or
(Answer instead of comment.) Consider using List.all : ('a -> bool) -> 'a list -> bool and List.exists : ('a -> bool) -> 'a list -> bool since they're short-circuiting, unlike List.foldl. There is really no point in folding farther than the first false in band's case, or true in bor's case. That is,
val band = List.all (fn b => b)
val bor = List.exists (fn b => b)
One definition for these library functions is found here:
fun all p [] = true
| all p (x::xr) = p x andalso all p xr;
fun exists p [] = false
| exists p (x::xr) = p x orelse exists p xr;
Since the list being fed to band and bor are already of type bool, passing the identity function (fn b => b) will produce the desired truth value. The functions are generic enough to work on any kind of list for which you can apply a predicate for each element, so if you were generating your bool list from some other list, you could avoid that step.
I've found out the problem: andalso and orelse are not operators nor functions cause they implement a short-circuit evaluation.
Therefore, the solution should be:
fun band x = foldl (fn (a,b) => a andalso b) true x;
fun bor x = foldr (fn (a,b) => a orelse b) false x;
There are no operators called and and or in SML. and is a keyword to separate multiple variable or declarations that are declared at the same time. There is no or.
The AND and OR logical operators are andalso and orelse which as you said in your own answer are short-circuiting, and not regular operators.

How to used Cons operator?

Basically the function will take one parameter as a character, number and check whether it is inside the List or not ?
let rec (member: a -> List a -> Bool) x =
| [] -> False
| Cons y ys -> if x == y then True else member x ys
;;
I got the solution but it seems too vague.
Could anyone show me how to use Cons operator in this particular case ?
Thanks
In Ocaml, the cons operator is ::. But it is not the only problem of your piece of code.
Here your function takes only one argument (x) but you use it with two (member x ys), you wanted to do let rec member x l = match l with or let rec member x = function which is equivalent.
In OCaml you don't have to give the type of your values, but if you do, this is not the rigth syntax. OCaml types are not capitalized, type parameters start with '
and are placed before the type they parameterize, then the type of your function is 'a -> 'a list -> bool. Moreover, for a function you have to give the type of the parameters and the return type separately (let rec member (x : 'a) (l : 'a list) : bool =).
The operator for equality is = and not ==.
Even if it is correct, don't use if then else to return a boolean, logical operators || and && should be used instead.
Corrected code:
let rec member x = function
| [] -> false
| y :: ys -> x = y || member x ys

How to do an addition on a list with a condition?

I have a university course about functional programming, where I use SML. As a preparation for the exam, I am working on some of the older exam sets without solutions.
One of the only questions I really have problems with is the following question using foldl:
Consider the program skeleton: fun
addGt k xs = List.foldl (...) ... xs;
Fill in the two missing pieces
(represented by the dots ...), so that
addGt k xs is the sum of those
elements in xs, which are greater than
k. For example, addGt 4 [1, 5, 2, 7,
4, 8] = 5 + 7 + 8 = 20
I am sure this is really easy, but I have a very hard time understanding the foldl and foldr functions.
What I have now is the following (which seems to be very wrong if you ask my compiler!):
fun addGt(k,xs) = List.foldl ( fn x => if x > k then op+ else 0) 0 xs;
I would really appreciate some help with this question, and maybe a very short comment which would cast some light on the foldl and foldr functions!
A solution that I just though of is the following:
fun addGt(k, xs) = List.foldl (fn (x, y) => if x >= 5 then x + y else y) 0 xs;
But let me explain. First of all check the type of the List.foldl function, it's:
('a * 'b -> 'b) -> 'b -> 'a list -> 'b
So List.foldl is a curried function that takes as first parameter another function of type ('a * 'b -> 'b). You used (fn x => if x > k then op+ else 0) which has type int -> int. You should instead provide List.foldl with a function that takes a tuple of type int * int and returns an int, so something like this: (fn (x, y) => do stuff). That's why your code didn't compile, you passed a wrong type of function in foldl.
Now you can think of foldl this way:
foldl f b [x_1, x_2, ..., x_(n - 1), x_n] = f(x_n, f(x_(n - 1), ..., f(x2, f(x1, b)) ...)) where f is a function of type ('a * 'b -> 'b), b is something of type 'b and the list [x_1, x_2, ..., x_(n - 1), x_n] is of type 'a list.
And similar for foldr you can think it in this way:
foldr f b [x_1, x_2, ..., x_(n - 1), x_n] = f(x_1, f(x_2, ..., f(x_(n - 1), f(x_ n, b))
If you call foldl f s ls on a list, ls = [x1, x2, ..., xn], then you get the result:
f(xn, ... f(x2, f(x1, s)))
That is, it starts by finding
a1 = f(x1, s)
Then
a2 = f(x2, a1)
and so on, until it's through the list.
When it's done, it returns an.
You can think of the a-values as being a sort of accumulator, that is, ai is the result as it would be if the list was only [x1, x2, ..., xi] (or rather, the first i elements of the list).
Your function will usually have the form:
fn (x, a) => ...
What you then need to do is think: Okay, if I have the next element in the list, x(i+1), and the value ai, which is the result for the list [x1, x2, ..., xi], what do I need to do to find the value a(i+1), which is the result for the list [x1, x2, ..., xi, x(i+1)].
s can be thought of as the value given to the empty list.
foldr works the same way, only you start from the back of the list instead of from the front.

Resources