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)
Related
I have a function great and it is implemented as below
let great y z = Option.bind (cons (Option.get z) >> Some) y
And I have the function apply as below
let apply f val =
match f with
| None -> None
| Some v -> Option.map v val
If I give the None value for the second parameter (z) it is giving me an error since Option.get z returns an error when it gets None.
I want to avoid this error without using if else blocks. I wonder is it possible to pass the great function to apply so that it can evaluate None when the given z parameter is None.
Any help would be appreciated.
If you want to execute the whole Option.bind ... thing only when z is Some, you can just use another Option.bind for that - that's exactly what bind is for:
let great y maybeZ =
Option.bind (fun z -> Option.bind (cons z >> Some) y) maybeZ
Or, to express it more elegantly:
let great maybeY maybeZ =
maybeZ |> Option.bind (fun z ->
maybeY |> Option.bind (cons z >> Some) )
The first line would then read like "bind maybeZ to z, and..."
In fact, I would probably do the same thing with y just for extra readability:
let great maybeY maybeZ =
maybeZ |> Option.bind (fun z ->
maybeY |> Option.bind (fun y ->
Some (z :: y) ) )
Alternatively, you can use Option.map2, which does exactly this: applies a function to two option-typed parameters when both are Some:
let great maybeY maybeZ =
Option.map2 (fun y z -> z :: y) maybeY maybeZ
And then you can eta-reduce it (but, sadly, only for maybeZ, due to the value restriction):
let great maybeY =
Option.map2 (fun y z -> z :: y) maybeY
Or you could get rid of the lambda instead if you just reversed the parameters:
let great maybeY maybeZ =
Option.map2 cons maybeZ maybeY
You can also write the great function using pattern matching like the apply function.
let great lOpt xOpt =
match lOpt, xOpt with
| Some l, Some x -> Some (x :: l)
| Some l, None -> Some l
| _ -> None
I have a basic append function
let append item list = item :: list
And i have a' list option and option Some("something")
let listOption = Some []
I want to add the value "something" to listOption. How can I do it without using pattern matching and Option.get but by lifting append function?
Any help would be appreciated
You can use maybe computation expression
type MaybeBuilder() =
member this.Bind(m, f) = Option.bind f m
member this.Return(x) = Some x
let maybe = new MaybeBuilder()
let append item list = item :: list
let appendLifted item list =
maybe {
let! l = list
let! i = item
return append i l
}
[<EntryPoint>]
let main argv =
appendLifted (Some "abc") (Some [])
0
It looks like a home work...
If you want to add a value (not an option) at the head of a list option, you can simply do this which will return None if the list option is None:
let liftedAppend item optList =
optList |> Option.bind (fun list -> Some (item :: list))
liftedAppend signature is:
'a -> 'a list option -> 'a list option
But talking about lifting stricto sensu, as the signature of your append function is:
'a -> 'a list -> 'a list
the signature of the lifted function should be:
'a option -> 'a list option -> 'a list option
That means the first argument have to be an option and I guess you want to check if it's Some or None. If so attentively read other's replies.
You can use something like this, which the de-sugared Lanayx's computation expression.
let liftedAppend optItem optList =
optList |> Option.bind (fun list ->
optItem |> Option.bind (fun item -> Some (item :: list)))
This works:
listOption
|> Option.map (append 11)
|> printfn "%A" // Some [11]
but to create a lifted append:
let liftedAppend v = Option.map (append v)
listOption
|> liftedAppend 11
|> printfn "%A" // Some [11]
The signature of the functions are:
val append : 'a -> 'a list > 'a list
val liftedAppend: 'a -> 'a list option -> 'a list option
To pass both parameters as options you can use Option.map2:
let liftedAppend2 vO = vO |> Option.map2 append
listOption
|> liftedAppend2 (Some 11)
|> printfn "%A" // Some [11]
Which has signature:
val liftedAppend2: a option -> 'a list option -> 'a list option
I have written a program that takes a message as a string and returns an anagram by padding the message with X's as needed such that the string length has exactly 4 factors then essentially rearranges the message as if it had been organized in a grid and read down instead of across. For example, inputting, "Haskell" would return the string, "HealslkX". I have written a program that encodes this anagram, but am having trouble writing a program that can reverse the previous program and decode the anagram, particularly with the removeX function that should remove the X padding. Here is what I have:
encode:
import Data.List
factors :: Int -> [Int]
factors n = [x | x <- [1..n], n `mod` x == 0]
split :: Int -> [a] -> [[a]]
split _ [] = []
split n xs =
let (ys, zs) = splitAt n xs
in ys : split n zs
encode :: [Char] -> [Char]
encode (x:xs) = if (length (factors (length xs))) == 4 then concat
(transpose (split ((factors (length xs))!!2) xs))
else encode (xs ++ ['X'])
decode:
import Data.List
factors :: Int -> [Int]
factors n = [x | x <- [1..n], n `mod` x == 0]
split :: Int -> [a] -> [[a]]
split _ [] = []
split n xs =
let (ys, zs) = splitAt n xs
in ys : split n zs
removeX :: [a] -> [a]
removeX xs = if (last xs) == 'X' then ((init xs) && removeX xs)
else xs
decode :: [Char] -> [Char]
decode (x:xs) = removeX (concat (transpose (split ((factors (length xs))!!1) xs)))
Just use removeX (init xs) instead of init xs && removeX xs. Haskell is not procedural (you don't write down a sequence of changes to make) but functional (you write down functions that produce new results from old). Haven't read the rest of the code to see if there are other errors, though.
Also consider removeX = reverse . dropWhile ('X'==) . reverse for better efficiency. Lists are singly-linked, so accesses and modifications at the end are relatively expensive.
https://ocaml.org/learn/tutorials/99problems.html
I am trying to understand the solution for generating the combinations of K distinct objects chosen from the N elements of a list. Here are the code:
let extract k list =
let rec aux k acc emit = function
| [] -> acc
| h :: t ->
if k = 1 then aux k (emit [h] acc) emit t else
let new_emit x = emit (h :: x) in
aux k (aux (k-1) acc new_emit t) emit t
in
let emit x acc = x :: acc in
aux k [] emit list;;
The emit function is defined to accept two parameters:
let emit x acc = x :: acc
So I don't quite understand how the following line works since it call emit giving only a single argument:
let new_emit x = emit (h :: x)
Also, the new_emit function accept only a single parameter and is passed as an argument to the aux function, how can it deal with the following line (the emit here is called by giving two arguments):
if k = 1 then aux k (emit [h] acc) emit t
Functions in OCaml are usually curried, meaning that multiple argument functions are expressed by taking one argument and returning a function that takes the next argument (and so on). OCaml has some syntax sugar to make this nicer to read: let f x y = ... is short for let f = fun x -> fun y -> ....
Usually programmers use such functions by passing all the arguments at once, but it is possible to only pass one and get back a 'partially applied' function as a result. That is what is happening with emit.
So you can read let emit_new x = emit (h :: x) as defining a version of emit with the first argument already supplied.
The point that you are missing here is that due to currying and first-class functions, the number of parameters of a function is not as rigid as you think it is.
In this particular case, the definition of emit as
let emit x acc = x :: acc
gives it the type 'a -> 'a list -> 'a list. This type can have two different readings, you can either think of it as a function that takes two argument, one of type 'a and one of type 'a list and returns an object of type 'a list. But, you can also read it as function that takes one argument of type 'a and returns a function of type 'a list -> 'a list.
The definition
let new_emit x = emit (h :: x)
is using this curried interpretation: since emit has for type
'a -> 'a list -> 'a list, applying it to h::x yields a function of type
'a list -> 'a list, consequently the function new_emit has for type
'a -> 'a list -> 'a list. In other words, the function new_emit still accepts two input parameters, even if it definitions only involve one argument. Note, to make things easier to understand the definition of new_emit can also be written either
let new_emit x = fun acc -> emit (h :: x) acc
or
let new_emit x acc = emit (h :: x) acc
In context, the emit element_list combination_list is used to add a new combination to the list of combinations by taking the element_list and adding to it all previously picked elements. The definition of new_emit is then used to pick the new element h. In other words, this line
if k = 1 then aux k (emit [h] acc) emit t else
means add the element list [h] plus all previously picked elements to the combination list since all elements have been picked, whereas
let new_emit x = emit (h :: x) in
aux k (aux (k-1) acc new_emit t) emit t
could be decomposed as:
First pick the element h:
let new_emit x = emit (h :: x)
then construct all combinations where h is present:
let combination_where_h_was_selected = aux (k-1) acc new_emit t
and then construct all combination where h is absent:
aux k combination_where_h_was_selected emit t
p.s.:
As a far more advanced remarks on the subject of the numbers of parameters of a function, note that even "variadic" function are perfectly possibly in OCaml. For instance, an abstruse and inefficient way to define list would be
let start f = f (fun x -> x)
let elt x t k = k (fun l -> t (fun l -> x ::l) l)
let stop f = f (fun x -> x) []
let [] = start stop
let l = start (elt 1) (elt 2) (elt 3) (elt 4) stop
;; assert ( l = [1;2;3;4] )
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