I want to print out the column of a matrix but i keep getting an error.
Error: This expression has type 'a list but an expression was expected of type int
let rec get_column2 mat x = match mat with
| [] -> raise (Failure "empty list")
| h::t -> if x = 1 then h else get_column2 t (x-1);;
let rec get_column mat x= match mat with
| [] -> raise (Failure "empty list")
| []::tv -> get_column tv x
| hv::tv -> get_column2 hv x::get_column tv x;;
Matrix example [[2;5;6];[3;5;3][3;6;8]]
The first part works fine on type int list so I added the second part to go through the int list list and cut them into int list's and then tryed to get the columns of each separately.
I also tryed it this way:
let rec get_column mat x =
let rec column matr y =
if matr = [] then raise (Failure "empty list") else
if y = 1 then List.hd matr else
column (List.tl matr) y-1;
in column (List.hd mat) x :: get_column (List.tl mat) x;;
The second example translates fine but then doesn't work. I get an Exception "tl". (I'm not sure the function nesting is done right since I'm just learning Ocaml).
get_column2 - your first function, works as it should. That is it will fetch the value of each row in the matrix. It's a good helper function for you to extract the value from a list.
Your second function get_column gets all the types right, and you're accumulating everything, except that instead of stopping when you have an empty list [] you end up throwing an exception. That is your matrix example will go through just nicely, until it has no more lists to go through, then it will always throw the exception. (because the recursion keeps going till it's an empty list, and Ocaml will do as you told it too, fail when it gets an empty list.
The only thing you were missing was the exception, instead of throwing an exception, just return an empty list. That way your recursion will go all the way and accumulate till it's an empty list, and at the final step where the matrix is empty, it will append the empty list to the result, and you're golden.
So your code should be:
let rec get_column2 mat x = match mat with
| [] -> raise (Failure "empty list")
| h::t -> if x = 1 then h else get_column2 t (x-1)
let rec get_column mat x= match mat with
| [] -> [] (*doesn't throw an exception here*)
| []::tv -> get_column tv x
| hv::tv -> (get_column2 hv x)::get_column tv x
Instead of throwing the exception when it's an empty list, maybe you could check if the value of x is more than the length of the inner list.
Also, here's my implementation of doing it. It's still fairly basic as it doesn't use List.iter which everyone loves, but it doesn't rely on any additional packages. It makes use of nested functions so you don't expose them everywhere and pollute the namespace.
(*mat is a list of int list*)
let get_col mat x =
let rec helper rows x = (*helper function that gets the value at x*)
match rows with
| [] -> raise (Failure "empty list")
| h::t -> if x = 1 then h else helper t (x-1)
in
let rec wrapper mat= (*function that walks through all the rows*)
match mat with
| [] -> []
| rows::tl -> (helper rows x)::(wrapper tl) (*keep accumulating value*)
in wrapper mat
How you can visualize the [] -> [] part is that when the recursion is at it's final stage (mat is reduced to an empty list), the wrapper function returns the empty list, which will be appended to the recursion stack (since we are accumulating the values in a list as per (helper rows x)::(wrapper tl)), and the recursion will complete.
You don't hit this error with your get_column2 as you tell ocaml to stop recursing and return a value when x=1.
Edit, Additional:
As Jeffrey mentioned, a much more elegant way of handling the error is adding the case for [row], where row is the last row in the matrix. You just return (helper row x) there. And you could have the empty matrix as a failure.
Example using your code:
let rec get_column mat x= match mat with
| [] -> raise (Failure "empty list") (*fail here, as we don't want to compute a matrix with no rows.*)
| [tv] -> get_column tv x (*just return the value*)
| hv::tv -> (get_column2 hv x)::get_column tv x
When I try your first example, I don't get a type error. When I run it, I get the "empty list" failure. So your description of your problem seems wrong.
If you want to treat an empty matrix as an error, you must be very careful to handle a 1 x n matrix as your base case. I don't see that in your code.
Related
I'm trying to write a function that finds the longest running sub-list of increasing integers in a list.
This is what I have so far (very long variable names to help me understand it better):
let increasing list =
let rec aux inputList currentLongestList currentHighestList lastInsertedElement =
match inputList with
| [] ->
if List.length currentLongestList > List.length currentHighestList then currentLongestList
else currentLongestList
| hd :: tl ->
if hd > lastInsertedElement then aux tl (currentLongestList # hd) currentHighestList hd
else aux tl currentLongestList currentHighestList lastInsertedElement
in
aux list [] [] [min_int]
;;
My issue is that when this is entered, it says val increasing : int list list -> int list = <fun> implying 2 lists need to be passed where I only want one in the function? What am I doing wrong? Also, the function doesn't work if I take away the square brackets from min_int, even though I don't see why they're needed - what would I have to do to get rid of them?
The inferred type informs you that the argument named list is a list of lists of integers. Let us understand why, step by step.
First, the type checker has unified the type list with the type of inputList because of your call to aux at the end of the function increasing.
Second, the head of the aux argument named inputList is compared with lastInsertedElement in the second case of aux pattern-matching. Since lastInsertedElement is of type int list because of your initial call to aux, the type induces that inputList has type int list list.
For your second question, "why the brackets seem needed around min_int?". Look at the expression "... # hd". It implies that "hd" must be a list...
I have finally found an excellent entry point into functional programming with elm, and boy, do I like it, yet I still lack some probably fundamental elegance concerning a few concepts.
I often find myself writing code similar to the one below, which seems to be doing what it should, but if someone more experienced could suggest a more compact and direct approach, I am sure that could give some valuable insights into this so(u)rcery.
What I imagine this could boil down to, is something like the following
(<-> is a vector subtraction operator):
edgeDirections : List Vector -> List Vector
edgeDirections corners = List.map2 (\p v -> p <-> v) corners (shiftr 1 corners)
but I don't really have a satisfying approach to a method that would do a shiftr.
But the rules of stackoverflow demand it, here is what I tried. I wrote an ugly example of a possible usage for shiftr (I absolutely dislike the Debug.crash and I am not happy about the Maybe):
Given a list of vectors (the corner points of a polygon), calculate the directional vectors by calculating the difference of each corner-vector to its previous one, starting with the diff between the first and the last entry in the list.
[v1,v2,v3] -> [v1-v3,v2-v1,v3-v2]
Here goes:
edgeDir : Vector -> ( Maybe Vector, List Vector ) -> ( Maybe Vector, List Vector )
edgeDir p ( v, list ) =
case v of
Nothing ->
Debug.crash ("nono")
Just vector ->
( Just p, list ++ [ p <-> vector ] )
edgeDirections : List Vector -> List Vector
edgeDirections corners =
let
last =
List.head <| List.reverse corners
in
snd <| List.foldl edgeDir ( last, [] ) corners
main =
show <| edgeDirections [ Vector -1 0, Vector 0 1, Vector 1 0 ]
I appreciate any insight into how this result could be achieved in a more direct manner, maybe using existing language constructs I am not aware of yet, or any pointers on how to lessen the pain with Maybe. The latter may Just not be possible, but I am certain that the former will a) blow me away and b) make me scratch my head a couple times :)
Thank you, and many thanks for this felicitous language!
If Elm had built-in init and last functions, this could be cleaner.
You can get away from all those Maybes by doing some pattern matching. Here's my attempt using just pattern matching and an accumulator.
import List exposing (map2, append, reverse)
shiftr list =
let shiftr' acc rest =
case rest of
[] -> []
[x] -> x :: reverse acc
(x::xs) -> shiftr' (x::acc) xs
in shiftr' [] list
edgeDirections vectors =
map2 (<->) vectors <| shiftr vectors
Notice also the shortened writing of the mapping function of (<->), which is equivalent to (\p v -> p <-> v).
Suppose Elm did have an init and last function - let's just define those quickly here:
init list =
case list of
[] -> Nothing
[_] -> Just []
(x::xs) -> Maybe.map ((::) x) <| init xs
last list =
case list of
[] -> Nothing
[x] -> Just x
(_::xs) -> last xs
Then your shiftr function could be shortened to something like:
shiftr list =
case (init list, last list) of
(Just i, Just l) -> l :: i
_ -> list
Just after I "hung up", I came up with this, but I am sure this can still be greatly improved upon, if it's even correct (and it only works for n=1)
shiftr : List a -> List a
shiftr list =
let
rev =
List.reverse list
in
case List.head rev of
Nothing ->
list
Just t ->
[ t ] ++ (List.reverse <| List.drop 1 rev)
main =
show (shiftr [ 1, 2, 3, 4 ] |> shiftr)
I have the following function in OCaml:
let get_all_parents lst =
List.map (fun (name,opt) -> opt) lst
That maps my big list with (name, opt) to just a list of opt. An option can contain of either None or Some value which in this case is a string. I want a list of strings with all my values.
I am a beginner learning OCaml.
I don't think filter and map used together is a good solution to this problem. This is because when you apply map to convert your string option to string, you will have the None case to deal with. Even if you know that you won't have any Nones because you filtered them away, the type checker doesn't, and can't help you. If you have non-exhaustive pattern match warnings enabled, you will get them, or you will have to supply some kind of dummy string for the None case. And, you will have to hope you don't introduce errors when refactoring later, or else write test cases or do more code review.
Instead, you need a function filter_map : ('a -> 'b option) -> 'a list -> 'b list. The idea is that this works like map, except filter_map f lst drops each element of lst for which f evaluates to None. If f evaluates to Some v, the result list will have v. You could then use filter_map like so:
filter_map (fun (_, opt) -> opt) lst
You could also write that as
filter_map snd lst
A more general example would be:
filter_map (fun (_, opt) ->
match opt with
| Some s -> Some (s ^ "\n")
| None -> None)
lst
filter_map can be implemented like this:
let filter_map f lst =
let rec loop acc = function
| [] -> List.rev acc
| v::lst' ->
match f v with
| None -> loop acc lst'
| Some v' -> loop (v'::acc) lst'
in
loop [] lst
EDIT For greater completeness, you could also do
let filter_map f lst =
List.fold_left (fun acc v ->
match f v with
| Some v' -> v'::acc
| None -> acc) [] lst
|> List.rev
It's a shame that this kind of function isn't in the standard library. It's present in both Batteries Included and Jane Street Core.
I'm going to expand on #Carsten's answer. He is pointing you the right direction.
It's not clear what question you're asking. For example, I'm not sure why you're telling us about your function get_all_parents. Possibly this function was your attempt to get the answer you want, and that it's not quite working for you. Or maybe you're happy with this function, but you want to do some further processing on its results?
Either way, List.map can't do the whole job because it always returns a list of the same length as its input. But you need a list that can be different lengths, depending on how many None values there are in the big list.
So you need a function that can extract only the parts of a list that you're interested in. As #Carsten says, the key function for this is List.filter.
Some combination of map and filter will definitely do what you want. Or you can just use fold, which has the power of both map and filter. Or you can write your own recursive function that does all the work.
Update
Maybe your problem is in extracting the string from a string option. The "nice" way to do this is to provide a default value to use when the option is None:
let get default xo =
match xo with
| None -> default
| Some x -> x
# get "none" (Some "abc");;
- : string = "abc"
# get "none" None;;
- : string = "none"
#
type opt = Some of string | None
List.fold_left (fun lres -> function
(name,Some value) -> value::lres
| (name,None) -> lres
) [] [("s1",None);("s2",Some "s2bis")]
result:
- : string list = ["s2bis"]
I am working on writing a recursive function in erlang that given an element X and a list, deletes the element X from the list and returns the new list. I believe I have written it correctly, however, when I run a test on it, I am thrown into an infinite loop..
delete(_,[]) -> [];
delete(X,[X|_]) -> [];
delete(X,[Y|YS]) ->
if X == Y -> YS;
true -> [Y] ++ delete(X,[YS]) % I believe the infinite loop is a result of this line..
end.
I am very new to erlang (this is my second project using the language), so troubleshooting is a bit difficult for me, but if anyone could provide some guidance, it would be much appreciated. Thank you in advance!
delete(_,[]) -> []; %% ok removing anything from an empty list gives an empty list
delete(X,[X|_]) -> []; %% big mistake. If you find the element you want to remove on top
%% of the list, you must remove it and continue with the rest of the list
delete(X,[Y|YS]) ->
if X == Y -> YS; %% this will never occurs since you already test this case
%% in the previous clause. An the result should be delete(X,YS), not YS.
true -> [Y] ++ delete(X,[YS]) %% correct
end.
I don't see where you have an infinite loop, but the second clause will make the recursive calls stop too early.
So your code should be:
delete(_,[]) -> [];
delete(X,[X|Rest]) -> delete(X,Rest);
delete(X,[Y|YS]) -> [Y] ++ delete(X,[YS]).
but a I would recommend to use list comprehension for a very short code and fast execution (it is the code used in lists:filter/2):
delete(X,L) -> [Y || Y <- L, Y =/= X].
% ^ ^ ^
% | | |_ when Y different from X
% | |_________ with all the elements Y from L
% |__________________ make a list
defining the function in the shell, you get:
1> D = fun D(_,[]) -> [];
1> D(X,[X|R]) -> D(X,R);
1> D(X,[Y|R]) -> [Y] ++ D(X,R) end.
#Fun<erl_eval.36.90072148>
2> D(4,[1,2,3,4,5,6]).
[1,2,3,5,6]
3> D1 = fun(X,L) -> [Y || Y <- L, Y =/= X] end.
#Fun<erl_eval.12.90072148>
4> D1(4,[1,2,3,4,5,6]).
[1,2,3,5,6]
5>
First off, I don't know why you would need the second clause. Basically it's saying "If the first item in the list matches the item to be removed, through the whole list away and return an empty one".
The easiest way to do this is to start with the list and an empty list to store the result. Then as we iterate over the items in the list, we add items that don't match to the result and ignore items that match the item we want deleted. This will remove all occurrences of X in List:
delete(X, List) -> delete(X, List, []). % Provide the same API as before
delete(_,[], Result) -> Result; % If the list is empty we are done.
delete(X,[Y|YS], Result) ->
case X == Y of
true ->
delete(X,[YS], Result);
false ->
delete(X,[Y|YS], Result)
end.
But why not use lists:filter/2? It makes it much simpler:
delete(X, List) ->
lists:filter(fun(Item) ->
Item /= X
end, List).
I recently started with F# and implemented a very basic recursive function that represents the Sieve of Eratosthenes. I came up with the following, working code:
static member internal SieveOfEratosthenesRecursive sequence accumulator =
match sequence with
| [] -> accumulator
| head::tail -> let rest = tail |> List.filter(fun number -> number % head <> 0L)
let newAccumulator = head::accumulator
Prime.SieveOfEratosthenesRecursive rest newAccumulator
This function is not really memory efficient so I tried to eliminate the variables "rest" and "newAccumulator". I came up with the following code
static member internal SieveOfEratosthenesRecursive sequence accumulator =
match sequence with
| [] -> accumulator
| head::tail -> tail |> List.filter(fun number -> number % head <> 0L)
|> Prime.SieveOfEratosthenesRecursive (head::accumulator)
As far as I understand the tutorials I've read Prime.SieveOfEratosthenesRecursive will be called with the filtered tail as first parameter and a list consisting of head::accumulator as second one. However when I try to run the code with the reduced variable usage, the program gets trappen in an infinite loop. Why is this happening and what did I do wrong?
As far as I understand the tutorials I've read Prime.SieveOfEratosthenesRecursive will be called with the filtered tail as first parameter and a list consisting of head::accumulator as second one.
You have this backwards.
In the first version, you're passing rest then newAccumulator; in the second version, you're effectively passing newAccumulator then rest. I.e., you've transposed the arguments.
Prime.SieveOfEratosthenesRecursive (head::accumulator) is a partial function application wherein you're applying (head::accumulator) as the first argument (sequence). This partial function application yields a unary function (expecting accumulator), to which you are passing (via |>) what is called rest in the first version of your code.
Changing SieveOfEratosthenesRecursive's argument order is the easiest solution, but I would consider something like the following idiomatic as well:
static member internal SieveOfEratosthenesRecursive sequence accumulator =
match sequence with
| [] -> accumulator
| head::tail ->
tail
|> List.filter(fun number -> number % head <> 0L)
|> Prime.SieveOfEratosthenesRecursive <| (head::accumulator)
or
static member internal SieveOfEratosthenesRecursive sequence accumulator =
let inline flipzip a b = b, a
match sequence with
| [] -> accumulator
| head::tail ->
tail
|> List.filter(fun number -> number % head <> 0L)
|> flipzip (head::accumulator)
||> Prime.SieveOfEratosthenesRecursive
FWIW, eliminating rest and newAccumulator as named variables here is not going to impact your memory usage in the slightest.
The last call in your second function is equivalent to:
Prime.SieveOfEratosthenesRecursive newAccumulator rest
where you switch positions of two params. Since newAccumulator grows bigger after each recursive call, you will never reach the base case of empty list.
The rule of thumb is putting the most frequently changing parameter at last:
let rec sieve acc xs =
match xs with
| [] -> acc
| x::xs' -> xs' |> List.filter (fun y -> y % x <> 0L)
|> sieve (x::acc)
The above function could be shortened using function keyword:
let rec sieve acc = function
| [] -> acc
| x::xs' -> xs' |> List.filter (fun y -> y % x <> 0L)
|> sieve (x::acc)
Using pipe (|>) operator only makes the function more readable, it doesn't affect memory usage at all.