I would like to create a function that produces two outputs.
Please consider the following example:
I built two functions that, given a list of integers, return a list of elements in even position and elements in odd position.
let rec alternate1 lst =
match lst with
[] -> []
| [x] -> []
| x::y::xs -> y::(alternate1 xs)
let rec alternate2 lst =
match lst with
[] -> []
| [x] -> [x]
| x::y::xs -> x::(alternate2 xs)
And here everything is fine. Now, the problem: I would like to create a single function alternate that returns both lists with signature alternate: int list-> (int list * int list).
let rec alternate lst =
match lst with
[] -> []
| [x] -> []
| [x::y] -> [y]
(*My attempts:*)
| x::y::xs -> ((y::alternate xs), (x::alternate xs))
| x::y::xs -> [(y::alternate xs); (x::alternate xs)]
| x::y::xs -> ((y::alternate xs) && (x::alternate xs))
So far, no solution worked. I am pretty sure the problem is even silly, but my reference did not help me to solve the problem.
Since you're calling alternate recursively, the recursive call will also return you two outputs, so of course you can't treat that tuple as a list - as in y::alternate xs.
You have to first take the tuple apart, process the parts separately, and recombine them into a tuple before returning:
let nextXs, nextYs = alternate xs
x::nextXs, y::nextYs
And then, your base cases should also return two outputs - otherwise your function has unclear return type:
| [] -> [], []
| [x] -> [x], []
| [x; y] -> [x], [y]
(also note that your match case [x::y] actually matches a list of lists, which contains exactly one list, in which the first element will be named x, and the tail of the list will be named y. In order to match a list of exactly two elements, use [x; y] or x::y::[])
Combining it together:
let rec alternate lst =
match lst with
| [] -> [], []
| [x] -> [x], []
| [x; y] -> [x], [y]
| x::y::rest ->
let nextXs, nextYs = alternate rest
x::nextXs, y::nextYs
Also: technically, the [x; y] base case is not needed, because it would be covered by the last case just fine.
Fyodor's answer is complete (as usual)
So I just wanted to add a tail-recursive version of his code (along with some reduction) to those who wanted to know how to make it tail-recursive (using continuation-passing style)
let alternate xs =
let aux cont even odd (evens, odds) = cont (even :: evens, odd :: odds)
let rec loop cont = function
| [] | [_] as xs -> cont (xs, [])
| even :: odd :: xs -> loop (aux cont even odd) xs
loop id xs
Alternatively one can use 2 continuation for each side list, but here I think it's not so useful as both sides are manipulated each time, but anyway
let alternate xs =
let aux cont x xs = cont (x :: xs)
let rec loop evenCont oddCont = function
| [] | [_] as xs -> evenCont xs, oddCont []
| even :: odd :: xs -> loop (aux evenCont even) (aux oddCont odd) xs
loop id id xs
Related
I tried to practice haskell a bit but I didn't get the following code to work:
rems :: Int -> [Int] -> [Int]
rems _ [] = []
rems k (x:xs)
| k == x = rems k xs
| otherwise [x] ++ rems k xs
main = print $
rems 3 [5, 3, 2]
This function removes every k from a list x if you call it rems k x. I know that it should be working because we wrote it down in university.
I'm using this IDE: https://repl.it/languages/haskell
It might be useful to know that otherwise isn't a keyword or special symbol like =, it's actually simply a boolean value defined in the prelude as True. I.e., a guard with otherwise works syntactically the same as any other guard, just the condition is trivial. You might also write it
rems _ [] = []
rems k (x:xs)
| k == x = rems k xs
| True = [x] ++ rems k xs
The alignment I chose above (all = aligned and at least two† spaces away from the guard-condition) is completely a matter of taste, but I think it helps avoiding confusion like the one you've found yourself in.
BTW, [x] ++ ... can be shortened to x : .... The preferred form of writing the function is
rems _ [] = []
rems k (x:xs)
| k==x = rems k xs
| otherwise = x : rems k xs
†Most people align the =s but use only one space. That's ok, but IMO k == x = res looks deceptive with all those equals-characters, and k and x further away from each other than from the result. k==x = res seems tidier.
I need to write a function in OCaml that adds elements of two lists in two different recursions: simple and tail. I made one with simple:
let rec add1 a b =
match (a, b) with
([], []) -> []
| (head1::tail1, []) -> head1 :: add1 tail1 []
| ([], head2::tail2) -> head2 :: add1 [] tail2
| (head1::tail1, head2::tail2) -> head1 + head2 :: add1 tail1 tail2
;;
It works like this:
add1 [1;2;3] [4;5;6;7];;
This return:
int list = [5; 7; 9; 7]
[1+4; 2+5; 3+6; 0+7] : 0 is added to 7 because there are no element on such position in first list.
So, my question is:
How can I make it with tail recursion?
The way to make this tail recursive is to build the result backwards and pass it along in the recursion and reverse it at the end.
let add1 a b =
let rec loop acc = function
| (xs, [])
| ([], xs) -> List.rev_append acc xs
| (x::xs, y::ys) -> loop ((x + y)::acc) (xs, ys)
in
loop [] (a, b)
Note: If one list is longer then the other then you don't need to add 0 to each element. The tail is already the result. So I use List.rev_append to reverse the accumulated values and append the remaining tail in one go.
Note2: List.rev_append can also append the empty list so no match for ([], []) is needed.
Tail recursion consists in having recursive function that simply performs a call to themselves without any other operations.
The following factorial is not tail recursive, because the last statement does not perform a simple call to fact but require a multiplcation :
let rec fact n =
if n = 0 then 1
else n*(fact (n-1))
By using an accumulator you can make this function tail recursive, the last statement performs a call to fact and therefore can be compiled using a jump and not a call :
let rec fact n r =
if n = 0 then r
else fact (n-1) (r*n)
And the usage :
fact 5 1
For you list addition, you can proceed the same way if the 2 lists have the same length at least.
let rec n_cartesian_product = function
| [] -> [[]]
| x :: xs ->
let rest = n_cartesian_product xs
List.concat (List.map (fun i -> List.map (fun rs -> i :: rs) rest) x)
Hello! I wrote this function but I need to write it without using any List.* built-in functions. Since there's an inner function that calls an outer function, I assume I must define two mutually recursive functions.
Defining a concat function seemed easy:
let rec list_concat ( lst : 'a list list ) : 'a list =
match lst with
[] -> []
|x::xs -> x # (list_concat xs)
The problem is, I'm stuck at the definition of the functions which yield the argument for concat:
let rec fun_i rest =
match rest with
[] -> []
|x::xs -> fun_rs
and fun_rs =
fun_i :: fun_rs
I can't seem to devise a proper solution. Can you help me?
edit: for instance, given this input
[["A";"a"];["B";"b"];["C";"c"]]
I want this output:
[["A"; "B"; "C"]; ["A"; "B"; "c"]; ["A"; "b"; "C"]; ["A"; "b"; "c"];
["a"; "B"; "C"]; ["a"; "B"; "c"]; ["a"; "b"; "C"]; ["a"; "b"; "c"]]
N-Cartesian Product
To define the n cartesian product recursively, the easiest method is just to make recursive definitions of the functions used in your original (non-recursive) example:
let rec list_concat lst =
match lst with
|[] -> []
|x::xs -> x # (list_concat xs)
let rec list_map f lst =
match lst with
|[] -> []
|x::xs -> (f x) :: list_map f xs
let rec n_cartesian_product =
function
| [] -> [[]]
| x :: xs ->
let rest = n_cartesian_product xs
list_concat (list_map (fun head -> list_map (fun tail -> head :: tail) rest) x)
In terms of writing idiomatically in F#, it's best to write using more general functions (like fold), rather than making a lot of custom functions with explicit recursion. So, you could define some additional functions:
let list_collect f = list_concat << list_map f
let rec list_fold f acc lst =
match lst with
|[] -> acc
|hd::tl -> list_fold f (f acc hd) tl
let n_cartesian_product_folder rest first =
list_collect (fun head -> list_map (fun tail -> head :: tail) rest) first
Then we can redefine n_cartesian_product simply as:
let n_cartesian_product2 lst = list_fold (n_cartesian_product_folder) [[]] lst
If we were using F# core library functions (rather than custom recursive implementations) this approach would involve more standard code with less to go wrong.
Cartesian Product
(I'll leave this part here since apparently it was useful)
Define a function that takes a list of 'a and make a list of 'b * 'a where all of the things of type 'b are some supplied element y.
/// take a list of 'a and make a list of (y, 'a)
let rec tuplify y lst =
match lst with
|[] -> []
|x::xs -> (y, x) :: (tuplify y xs)
Then define a function that recurses through both my lists, calling tuplify on the current element of the first list and the entire second list and concat that with the recursive call to cartesian product.
/// cartesian product of two lists
let rec cartesianProduct lst1 lst2 =
match lst1 with
|[] -> []
|x::xs -> tuplify x lst2 # (cartesianProduct xs lst2)
I'm attempting to make a function that generates the last item in a list. I want to use reverse and !!. This is what I have so far:
myLast :: [a] -> [a] -> Int -> a
myLast xs = (reverse xs) !! 1
I know the problem lies somewhere within the type, but I'm having trouble identifying how to fix it.
A function's type signature has nothing to do with what you use in the function, it only describes how other people can use this function you're defining. So by writing
myLast :: [a] -> [a] -> Int -> a
you're saying, users need to supply two lists and and integer. Just to get the last element of one of the lists?? That doesn't make sense.
You surely mean
myLast :: [a] -> a
You should generally write that down before even thinking about how you're going to implement that function.
With that signature, you can write various implementations:
myLast :: [a] -> a
myLast xs = head $ reverse xs
myLast' :: [a] -> a
myLast' [l] = l
myLast' (_:xs) = myLast' xs
myLast'' :: [a] -> a
myLast'' = fix $ \f (x:xs) -> maybe x id . teaspoon $ f xs
or whatever weird implementation you choose, it has nothing to do with the signature.
On an unrelated note: though last is actually a standard function from the prelude, it's a kind of function avoided in modern Haskell: last [] gives an error, because the is no a value to be found in the empty list! Errors are bad. Hence the “ideal” way to write it is actually
myLast :: [a] -> Maybe a
myLast [] = Nothing
myLast [x] = x
myLast (_:xs) = myLast xs
I would recommend not using !! at all, but to use head.
myLast xs = head (reverse xs)
Head returns the first element of the list it is given as argument.
If you insist on using !!, in Haskell arrays are indeed zero-based, which means that !! 0 gets the first element, !! 1 the second, etc.
As for the type: myLast takes an array of some type and returns one item of that same type. That is denoted as follows:
myLast :: [a] -> a
#leftaroundabout covered this way better in his answer.
Based on #leftaroundabout 's answer, here's an implementation that should do what you want:
safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:_) = Just x
myLast :: [a] -> Maybe a
myLast [] = Nothing
myLast xs = safeHead $ reverse xs
The Maybe type is constructed as follows (from Hackage):
data Maybe a = Nothing | Just a
deriving (Eq, Ord)
myLast [1, 2, 3, 4], for example, will return Just 4. If you want to use the value 4 you can use the function fromJust function from the Data.Maybe module (fromJust (Just 4) returns 4). fromJust is defined like this:
-- | The 'fromJust' function extracts the element out of a 'Just' and
-- throws an error if its argument is 'Nothing'.
--
-- ==== __Examples__
--
-- Basic usage:
--
-- >>> fromJust (Just 1)
-- 1
--
-- >>> 2 * (fromJust (Just 10))
-- 20
--
-- >>> 2 * (fromJust Nothing)
-- *** Exception: Maybe.fromJust: Nothing
--
fromJust :: Maybe a -> a
fromJust Nothing = error "Maybe.fromJust: Nothing" -- yuck
fromJust (Just x) = x
I am currently trying to make use functions to create:
0 V12 V13 V14
V21 0 V23 V24
V31 V32 0 V34
V41 V42 V43 0
A way that I found to do this was to use theses equations:
(2*V1 - 1)*(2*V2-1) = for spot V(1,2) in the Matrix
(2*V1 - 1)*(2*V3-1) = for spot V(1,3) in the Matrix
etc
Thus far I have:
let singleState state =
if state = 0.0 then 0.0
else
((2.0 *. state) -. 1.0);;
let rec matrixState v =
match v with
| [] -> []
| hd :: [] -> v
| hd :: (nx :: _ as tl) ->
singleState hd *. singleState nx :: matrixState tl;;
My results come out to be:
float list = [-3.; -3.; -3.; -1.]
When they should be a list of lists that look as follows:
0 -1 1 -1
-1 0 -1 1
1 -1 0 -1
-1 1 -1 0
So instead of it making list of lists it is making just one list. I also have trouble figuring out how to make the diagonals 0.
The signatures should look like:
val singleState : float list -> float list list = <fun>
val matrixState : float list list -> float list list = <fun>
and I am getting
val singleState : float -> float = <fun>
val matrixState : float list -> float list = <fun>
Any ideas?
With some fixing up, your function would make one row of the result. Then you could call it once for each row you need. A good way to do the repeated calling might be with List.map.
Assuming this is mostly a learning exercise, it might be good to first make a matrix like this:
V11 V12 V13 V14
V21 V22 V23 V24
V31 V32 V33 V34
V41 V42 V43 V44
I think this will be a lot easier to calculate.
Then you can replace the diagonal with zeroes. Here's some code that would replace the diagonal:
let replnth r n l =
List.mapi (fun i x -> if i = n then r else x) l
let zerorow row (n, res) =
(n - 1, replnth 0.0 n row :: res)
let zerodiag m =
let (_, res) = List.fold_right zerorow m (List.length m - 1, []) in
res
I would prefer to go with an array for your work.
A nice function to use is then Array.init, it works like so,
# Array.init 5 (fun x -> x);;
- : int array = [|0; 1; 2; 3; 4|]
We note that 5 play the role of the size of our Array.
But as you want a matrix we need to build an Array of Array which is achieve with two call of Array.init, the last one nested into the first one,
# Array.init 3 (fun row -> Array.init 3 (fun col -> row+col));;
- : int array array = [|[|0; 1; 2|]; [|1; 2; 3|]; [|2; 3; 4|]|]
Note, I've called my variable row and col to denote the fact that they correspond to the row index and column index of our matrix.
Last, as your formula use a vector of reference V holding value [|V1;V2;V3;V4|], we need to create one and incorporate call to it into our matrix builder, (The value hold on the cell n of an array tab is accessed like so tab.(n-1))
Which finally lead us to the working example,
let vect = [|1;2;3;4|]
let built_matrix =
Array.init 4 (fun row ->
Array.init 4 (fun col ->
if col=row then 0
else vect.(row)+vect.(col)))
Of course you'll have to adapt it to your convenience in order to match this piece of code according to your requirement.
A side note about syntax,
Repeating Array each time can be avoid using some nice feature of OCaml.
We can locally open a module like so,
let built_matrix =
let open Array in
init 4 (fun row ->
init 4 (fun col ->
if col=row then 0
else vect.(row)+vect.(col)))
Even shorter, let open Array in ... can be write as Array.(...), Below a chunk of code interpreted under the excellent utop to illustrate it (and I going to profit of this opportunity to incorporate a conversion of our matrix to a list of list.)
utop #
Array.(
to_list
## map to_list
## init 4 (fun r ->
init 4 (fun c ->
if r = c then 0
else vect.(r)+ vect.(c))))
;;
- : int list list = [[0; 3; 4; 5]; [3; 0; 5; 6]; [4; 5; 0; 7]; [5; 6; 7; 0]]
I hope it helps