I want to create a non-recursive function for my minimum
but I have some troubles with it
Can you help me please.
`let min_list lst=
let n=list.length lst ;;
let a=list.nth lst ;;
for i = 1 to n-1 ;;
let b=list.nth lst i;;
if a >b then a=b lst done ;;`
Honesly,It's difficult with non recursive fonction.So this is just for learning.I still have erreur in ligne 6
let min_list lst=
let a=List.hd lst in
let n=List.length lst in
for j =1 to n-1 do
let b=List.nth lst j in
if a > b then (let a=b) done ;;
Thank you it's useful It help me a lot .I have one other question what the difference between this
let min_array a =
let min =ref (List.hd a) in
for i = 1 to List.length a -1 do
if List.nth a i < !min then min := List.nth a i
done;
!min;;
print_int (min_array [ 10 ; 5 ; 7 ; 8 ; 12 ]);;
and
let min_array a =
let min =ref (List.hd a) in
for i = 1 to List.length a -1 do
if ref (List.nth a i) < min then min := List.nth a i
done;
!min;;
print_int (min_array [ 10 ; 5 ; 7 ; 8 ; 12 ]);;
It's the same ?I think
Why don't you want to use a recursive function ?
Liste are made to be crossed by recursive function. Everytime you use List.nth l n Ocaml has to cross n values until he found the nth element.
In Ocaml you can't change variable value as you do in other languages. You want a to be a ref.
Also your function won't return anything you'll have to put a !a between the done and the ;;. There will be a ! Because a will be a ref.
But if you want to practice use arrays instead because what you do here is in complexity O(n²) instead of O(n).
As said in the answer from Butanium, this kind of non-recursive function might be more relevant with arrays. And to work with mutable values, you need to use a reference.
A solution might then be something like (without dealing with case of an empty array):
let min_array a =
let min = ref a.(0) in
for i = 1 to Array.length a -1 do
if a.(i) < !min then min := a.(i)
done;
!min
The last line is important here, because it gets the value to be returned by the function.
Can then be used like that:
# min_array [| 10 ; 5 ; 7 ; 8 ; 12 |];;
- : int = 5
If you really do want to use lists instead of arrays, just use List.nth a i instead of a.(i) and List.length instead of Array.length.
Edit after question update
As Shawn and Jeffrey Scofield said in their respective comment, you should try to understand a bit better OCaml's syntax. And please don't use ;; in your programs, just keep it for the REPL.
As described in the documentation,
ref returns a fresh reference containing the given value.
Which means that when you write ref (List.nth a i) < min,
you create a fresh reference containing the i-th value the list, then compare it to min (which is also a reference). Luckily, mutable structures are compared by contents, which means that OCaml will access to your fresh reference's value, then access to min's value, and compare them. Thus, it will produce the same result as the direct comparison List.nth a i < !min, with a bit of useless memory allocation/access.
You can do this quite concisely by taking advantage of some features of the OCaml stdlib:
(* 'a list -> 'a option *)
let min_list l =
if List.length l > 0 then
Some (List.fold_left min (List.hd l) l)
else
None
Thanks to the min built-in, this works for lists of any type.
e.g. in a utop shell we can see:
min_list [99; 33; -1];;
- : int option = Some (-1)
min_list [99.1; 33.2; -1.3];;
- : float option = Some (-1.3)
min_list ["z"; "b"; "k"];;
- : string option = Some "b"
Explanation
First we recognise that the list may be empty, in which case we cannot return a meaningful value. This implies the function should return an option type, so either Some <value> or None.
Next we can use List.fold_left to iterate through the list.
Unfortunately the docs for List.fold_left are almost completely unhelpful:
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
fold_left f init [b1; ...; bn] is f (... (f (f init b1) b2) ...) bn.
It's as if they assume that if you're using OCaml you're already an elite master of functional programming, who naturally knows what a "fold left" does.
I'm not an elite master of functional programming, but I've been around long enough to know that fold_left is basically the same as the reduce function in Python.
It's a function that iterates through a list, applies a function to each value as it goes, and returns a single value.
So we can start to make sense of the signature of fold_left...
It takes three arguments:
The first arg, f, is a function which itself takes two args - the first or 'left' arg is the 'accumulated' value, and the second arg is the current value from the list as we iterate through. Whatever value you return from this function will be passed back into it as the left 'accumulated' value on the next iteration. When the list is exhausted the accumulated value will be returned from fold_left.
The second arg, init is an initial value. It is passed to f as the left 'accumulated' arg in the first step, when nothing has been otherwise accumulated yet.
Third arg is our list of values
So when we return:
Some (List.fold_left min (List.hd l) l)
...we are passing the min function as f and (List.hd l) as init.
List.hd l just returns the first element of the list l. We could use any element from the list as an initial value, but List.hd exists and gives us the first.
So fold_left is going to iterate through the list and f will return min <accumulated> <current>. So at each iteration step the accumulated value passed forward is the lowest value seen so far.
Non-recursive?
I did wonder if perhaps the fold_left method does not count as non-recursive somehow, since no one else had suggested it. Even though we have not used let rec anywhere, maybe somewhere internally it is secretly recursive?
For fun I decided to try writing the reduce/fold function from scratch:
let reduce f init l =
let acc = ref init in
List.iter (fun el -> acc := f !acc el) l;
!acc
(* we can directly substitute `reduce` for `List.fold_left` *)
let min_list l =
if List.length l > 0 then
Some (reduce min (List.hd l) l)
else
None
...again, no let rec needed so I guess it counts as non-recursive.
Related
Important: I am only allowed to use List.head, List.tail and List.length
No List.map List.rev ...........etc
Only List.hd, List.tl and List.length
How to duplicate the elements of a list in a list of lists only if the length of the list is odd
Here is the code I tried:
let rec listes_paires x =
if x=[] then []
else [List.hd (List.hd x)]
# (List.tl (List.hd x))
# listes_paires (List.tl x);;
(* editor's note: I don't know where this line is supposed to go*)
if List.length mod 2 = 1 then []
For exemple:
lists_odd [[]; [1];[1;2];[1;2;3];[];[5;4;3;2;1]];;
returns
[[]; [1; 1]; [1; 2]; [1; 2; 3; 1; 2; 3]; []; [5; 4; 3; 2; 1; 5; 4; 3; 2; 1]]
Any help would be very appreciated
thank you all
It looks like that your exercise is about writing recursive functions on lists so that you can learn how to write functions like List.length, List.filter, and so on.
Start with the most simple recursive function, the one that computes the length to the list. Recall, that you can pattern match on the input list structure and make decisions on it, e.g.,
let rec length xs = match xs with
| [] -> 0 (* the empty list has size zero *)
| hd :: tl ->
(* here you can call `length` and it will return you
the length of the list hing how you can use it to
compute the length of the list that is made of `tl`
prepended with `hd` *)
???
The trick is to first write the simple cases and then write the complex cases assuming that your recursive function already works. Don't overthink it and don't try to compute how recursion will work in your head. It will make it hurt :) Just write correctly the base cases (the simple cases) and make sure that you call your function recursively and correctly combine the results while assuming that it works correctly. It is called the induction principle and it works, believe me :)
The above length function was easy as it was producing an integer as output and it was very easy to build it, e.g., you can use + to build a new integer from other integers, something that we have learned very early in our lives so it doesn't surprise us. But what if we want to build something more complex (in fact it is not more complex but just less common to us), e.g., a list data structure? Well, it is the same, we can just use :: instead of + to add things to our result.
So, lets try writing the filter function that will recurse over the input list and build a new list from the elements that satisfy the given predicate,
let rec filter xs keep = match xs with
| [] -> (* the simple case - no elements nothing to filter *)
[]
| x :: xs ->
(* we call filter and it returns the correctly filtered list *)
let filtered = filter xs keep in
(* now we need to decide what to do with `x` *)
if keep x then (* how to build a list from `x` and `filtered`?*)
else filtered (* keep filtering *)
The next trick to learn with recursive functions is how to employ helper functions that add an extra state (also called an accumulator). For example, the rev function, which reverses a list, is much better to define with an extra accumulator. Yes, we can easily define it without it,
let rec rev xs = match xs with
| [] -> []
| x :: xs -> rev xs # [x]
But this is an extremely bad idea as # operator will have to go to the end of the first list and build a completely new list on the road to add only one element. That is our rev implementation will have quadratic performance, i.e., for a list of n elements it will build n list each having n elements in it, only to drop most of them. So a more efficient implementation will employ a helper function that will have an extra parameter, an accumulator,
let rev xs =
(* we will pump elements from xs to ys *)
let rec loop xs ys = match xs with
| [] -> ys (* nothing more to pump *)
| x :: xs ->
let ys = (* push y to ys *) in
(* continue pumping *) in
loop xs []
This trick will also help you in implementing your tasks, as you need to filter by the position of the element. That means that your recursive function needs an extra state that counts the position (increments by one on each recursive step through the list elements). So you will need a helper function with an extra parameter for that counter.
Im trying to add a tuple of type (int*int) on a for cycle to a list but i get an error saying : this expression should have type unit.
this is what i have right now:
let addtuple k lst =
for i=0 to k - 1 do
let (n,j) =Scanf.scanf " %d %d" (fun a b->(a,b))
in
(n,j)::lst
done;;
The purpose of the OCaml for is to do something, rather than compute a value. So the body of the loop should be an OCaml expression that has a useful side effect (like printing a value). For this reason, the body of a for loop should have the type unit, the type used for expressions that don't have an interesting value. But your loop has a body that is a list. The compiler is telling you (correctly) that this indicates that something is wrong.
Your code is written assuming that the expression (n, j) :: lst will change the value of lst. But this is not the case. In a functional language like OCaml, you can't change the values of variables.
If your function is supposed to return a list, it can't be based on a for loop, which always returns () (the unique value of type unit). Most likely it should be based on a fold (which accumulates a value while working through a series of inputs) or on your own recursive function.
With a for you need to use ref:
let addtuple k lst =
let r = ref lst in
for i = 1 to k do
r := (Scanf.scanf " %d %d" (fun x y -> (x, y))) :: !r
done;
!r;;
A more functional approach using a recursive function:
let rec addtuple k lst =
match k with
| 0 -> lst
| _ -> addtuple (k - 1) ((Scanf.scanf " %d %d" (fun x y -> (x, y))) :: lst);;
I am new to OCaml and functional programming as a whole. I am working on a part of an assignment where I must simply return the first n elements of a list. I am not allowed to use List.Length.
I feel that what I have written is probably overly complicated for what I'm trying to accomplish. What my code attempts to do is concatenate the front of the list to the end until n is decremented to 1. At which point the head moves a further n-1 spots to that the tail of the list and then return the tail. Again, I realize that there is probably a much simpler way to do this, but I am stumped and probably showing my inability to grasp functional programming.
let rec take n l =
let stopNum = 0 - (n - 1) in
let rec subList n lst =
match lst with
| hd::tl -> if n = stopNum then (tl)
else if (0 - n) = 0 then (subList (n - 1 ) tl )
else subList (n - 1) (tl # [hd])
| [] -> [] ;;
My compiler tells me that I have a syntax error on the last line. I get the same result regardless of whether "| [] -> []" is the last line or the one above it. The syntax error does not exist when I take out the nested subList let. Clearly there is something about nested lets that I am just not understanding.
Thanks.
let rec firstk k xs = match xs with
| [] -> failwith "firstk"
| x::xs -> if k=1 then [x] else x::firstk (k-1) xs;;
You might have been looking for this one.
What you have to do here, is to iterate on your initial list l and then add elements of this list in an accumulator until n is 0.
let take n l =
let rec sub_list n accu l =
match l with
| [] -> accu (* here the list is now empty, return the partial result *)
| hd :: tl ->
if n = 0 then accu (* if you reach your limit, return your result *)
else (* make the call to the recursive sub_list function:
- decrement n,
- add hd to the accumulator,
- call with the rest of the list (tl)*)
in
sub_list n [] l
Since you're just starting with FP, I suggest you look for the simplest and most elegant solution. What you're looking for is a way to solve the problem for n by building it up from a solution for a smaller problem.
So the key question is: how could you produce the first n elements of your list if you already had a function that could produce the first (n - 1) elements of a list?
Then you need to solve the "base" cases, the cases that are so simple that the answer is obvious. For this problem I'd say there are two base cases: when n is 0, the answer is obvious; when the list is empty, the answer is obvious.
If you work this through you get a fairly elegant definition.
Haskell
addm::[Int]->Int
addm (x:xs) = sum(x:xs)
I was able to achieve to get a sum of a list using sum function but is it possible to get the sum of a list using map function? Also what the use of map function?
You can't really use map to sum up a list, because map treats each list element independently from the others. You can use map for example to increment each value in a list like in
map (+1) [1,2,3,4] -- gives [2,3,4,5]
Another way to implement your addm would be to use foldl:
addm' = foldl (+) 0
Here it is, the supposedly impossible definition of sum in terms of map:
sum' xs = let { ys = 0 : map (\(a,b) -> a + b) (zip xs ys) } in last ys
this actually shows how scanl can be implemented in terms of map (and zip and last), the above being equivalent to foldl (+) 0 xs === last $ scanl (+) 0 xs:
scanl' f z xs = let { ys = z : map (uncurry f) (zip ys xs) } in ys
I expect one can calculate many things with map, arranging for all kinds of information flow through zip.
edit: the above is just a zipWith in disguise of course (and zipWith is kind of a map2):
sum' xs = let { ys = 0 : zipWith (+) ys xs } in last ys
This seems to suggest that scanl is more versatile than foldl.
It is not possible to use map to reduce a list to its sum. That recursive pattern is a fold.
sum :: [Int] -> Int
sum = foldr (+) 0
As an aside, note that you can define map as a fold as well:
map :: (a -> b) -> ([a] -> [b])
map f = fold (\x xs -> f x : xs) []
This is because foldr is the canonical recursive function on lists.
References: A tutorial on the universality and expressiveness of fold, Graham Hutton, J. Functional Programming 9 (4): 355–372, July 1999.
After some insights I have to add another answer: You can't get the sum of a list with map, but you can get the sum with its monadic version mapM. All you need to do is to use a Writer monad (see LYAHFGG) over the Sum monoid (see LYAHFGG).
I wrote a specialized version, which is probably easier to understand:
data Adder a = Adder a Int
instance Monad Adder where
return x = Adder x 0
(Adder x s) >>= f = let Adder x' s' = f x
in Adder x' (s + s')
toAdder x = Adder x x
sum' xs = let Adder _ s = mapM toAdder xs in s
main = print $ sum' [1..100]
--5050
Adder is just a wrapper around some type which also keeps a "running sum." We can make Adder a monad, and here it does some work: When the operation >>= (a.k.a. "bind") is executed, it returns the new result and the value of the running sum of that result plus the original running sum. The toAdder function takes an Int and creates an Adder that holds that argument both as wrapped value and as running sum (actually we're not interested in the value, but only in the sum part). Then in sum' mapM can do its magic: While it works similar to map for the values embedded in the monad, it executes "monadic" functions like toAdder, and chains these calls (it uses sequence to do this). At this point, we get through the "backdoor" of our monad the interaction between list elements that the standard map is missing.
Map "maps" each element of your list to an element in your output:
let f(x) = x*x
map f [1,2,3]
This will return a list of the squares.
To sum all elements in a list, use fold:
foldl (+) 0 [1,2,3]
+ is the function you want to apply, and 0 is the initial value (0 for sum, 1 for product etc)
As the other answers point out, the "normal" way is to use one of the fold functions. However it is possible to write something pretty similar to a while loop in imperative languages:
sum' [] = 0
sum' xs = head $ until single loop xs where
single [_] = True
single _ = False
loop (x1 : x2 : xs) = (x1 + x2) : xs
It adds the first two elements of the list together until it ends up with a one-element list, and returns that value (using head).
I realize this question has been answered, but I wanted to add this thought...
listLen2 :: [a] -> Int
listLen2 = sum . map (const 1)
I believe it returns the constant 1 for each item in the list, and returns the sum!
Might not be the best coding practice, but it was an example my professor gave to us students that seems to relate to this question well.
map can never be the primary tool for summing the elements of a container, in much the same way that a screwdriver can never be the primary tool for watching a movie. But you can use a screwdriver to fix a movie projector. If you really want, you can write
import Data.Monoid
import Data.Foldable
mySum :: (Foldable f, Functor f, Num a)
=> f a -> a
mySum = getSum . fold . fmap Sum
Of course, this is silly. You can get a more general, and possibly more efficient, version:
mySum' :: (Foldable f, Num a) => f a -> a
mySum' = getSum . foldMap Sum
Or better, just use sum, because its actually made for the job.
I have some code which is designed to replace a value in a list
replaceNth n newVal (x:xs)
| n == 0 = newVal:xs
| otherwise = x:replaceNth (n-1) newVal xs
For example, when I load the function into GHCI, I enter and get the following:
*Main> replaceNth 3 4 [3,3,3,3,3]
[3,3,3,4,3]
However I am trying to use this function for a multiple lists within a list and can't seem to do so (e.g.).
What I want is to get a result like this:
[[3,3,3,3,3],[3,3,3,**2**,3],[3,3,3,3,3]]
From this [[3,3,3,3,3],[3,3,3,3,3],[3,3,3,3,3]]
using something like the function above.
Your function is not general enough to handle the task you wish it to preform. In particular, you need to know what the replacement value will be before you call the function. To get this working you might either:
Select the nth list, compute the new list then use your function to put that replacement in the list of lists. OR (and better)
Make a more general function that instead of taking a new value takes a function from the old value to the new:
Example
replaceNth' :: Int -> (a -> a) -> [a] -> [a]
replaceNth' n f (x:xs)
| n == 0 = (f x):xs
| otherwise = x:replace (n-1) f xs
Now to solve you second problem:
let ls = [[3,3,3,3,3],[3,3,3,3,3],[3,3,3,3,3]]
in replaceNth' 1 (replaceNth' 3 (const 2)) ls
That is replace the second list with a list made by taking the fourth element of that list and replacing what ever it is with 2.
Make a function that applies a function to the nth element of a list instead. Then you can easily get what you want by composing that with itself and using const for the inner replacement.
perhaps this does what you want (applied to the list of lists):
replaceNth 1 (replaceNth 3 4 [3,3,3,3,3])
Using your existing definition:
ghci> let arg = [[3,3,3,3,3],[3,3,3,3,3],[3,3,3,3,3]]
ghci> replaceNth 1 (replaceNth 3 2 (arg !! 1)) arg
[[3,3,3,3,3],[3,3,3,2,3],[3,3,3,3,3]]
ghci>
To refactor it into a function:
replaceMthNth m n v arg = replaceNth m (replaceNth n v (arg !! m)) arg