How to create a function that encodes run-length using fold_right? - recursion

I created a function and helper function that find the number of repeating elements in a list, and what those elements.
let rec _encode l x =
match l with
| [] -> 0
| head::rest -> (if head = x then 1 else 0) + encode rest x
let encode l x = ((_encode l x), x)
In this case, I have to specify what that element is for it to search.
So this is a two part question. 1) How do I do it to return a list of tuples, with format (int * 'a) list, where int is the # of rep, and 'a is the element that is repeating.
2) How would I implement this using fold_right?
I was thinking something along the lines of:
let encode (l : 'a list) : (int * 'a) list = fold_right (fun (x,hd) lst ->
match x with
| [] -> 0
| hd :: rest -> if hd x then (x+1, hd) else (x, hd)) l []

Your attempt looks very confused:
It doesn't use lst, hd (the first one), or rest.
x is used as a list (match x with []) and a number (x+1).
The elements of x (list) are functions that return bools?? (... hd::rest -> ... if hd x)
The function sometimes returns a number (0) and sometimes a tuple ((x, hd)).
Here's how I'd do it:
let encode l =
let f x = function
| (n, y) :: zs when x = y -> (n + 1, y) :: zs
| zs -> (1, x) :: zs
in
fold_right f l []
Which is the same as:
let encode l =
let f x z = match z with
| (n, y) :: zs when x = y -> (n + 1, y) :: zs
| zs -> (1, x) :: zs
in
fold_right f l []
Which is the same as:
let encode l =
fold_right (fun x z ->
match z with
| (n, y) :: zs when x = y -> (n + 1, y) :: zs
| zs -> (1, x) :: zs
) l []

Related

How can I make use of cong and injective with indexed vectors in Idris?

cong and injective allow you to apply and unapply functions to equalities:
cong : (f : a -> b) -> x = y -> f x = f y
injective : Injective f => f x = f y -> x = y
Both of these fail for indexed vectors with different lengths, for obvious reasons.
How can I prove that two equal vectors have the same length? I.e.
sameLen : {xs : Vect n a} -> {ys : Vect m b} -> xs = ys -> n = m
I can't just do
sameLen pf = cong length pf
because length on xs has type Vect n a -> Nat and length on ys has type Vect m b -> Nat. (In fact, I'm not even sure how to prove the same thing for two regular Lists, due to the differing type arguments, never mind with the added indices).
Going the other way, how would I prove something like
data Rose a = V a | T (Vect n (Rose a))
Injective T where
injective Refl = Refl
unwrap : {xs : Vect n (Rose a)} -> {ys : Vect m (Rose b)} -> T xs = T ys -> xs = ys
Again, I can't just do
unwrap pf = injective pf
due to the differing types of T (one with m and one with n). And even if I had a proof m=n, how could I use that to convince Idris that the two applications of T are the same?
Got the answer from the Idris Discord - if you pattern match on Refl then it unifies a and b automatically:
sameLen : {xs : List a} -> {ys : List b} -> xs = ys -> length xs = length ys
sameLen Refl = Refl
sameLen' : {xs : Vect n a} -> {ys : Vect m b} -> xs = ys -> n = m
sameLen' Refl = Refl

OCaml function apparently works but does not return the expected result

Who can help? I am a beginner in OCaml, I am trying to perform an action of unpacking sets. Having a set [(1, 4); (2, 5); (3, 6)] I want to get the exit [(1,2,3), (4,5,6)]. I am using a script that I tested with Haskell and it worked, but in OCaml, it does not show the result. Where am I going wrong? I could not figure out where my mistake is. Thx.
let fst num1 num2 =
match num1, num2 with
| (x, y) -> x;;
let snd num1 num2 =
match num1, num2 with
| (x, y) -> y;;
let rec dcp_base list1 list2 list3 =
match list1, list2, list3 with
| (xs, ys, []) -> (xs, ys)
| (xs, ys, z :: zs) -> dcp_base (xs # [fst z]) (ys # [snd z]) zs;;
let descompact list =
match list with
| [] -> ([], [])
| xs -> dcp_base [] [] xs;;
The problem is your redefinition of fst and snd. They're not needed, as they're already defined in the standard library and in scope with exactly those names. But they're also wrong. Your implementation takes two arguments and selects either the first or second in a roundabout way by creating an intermediary tuple, instead of a singe tuple argument directly. Therefore, when you apply it to a single tuple argument it will return a partially applied function expecting the second argument.
You can fix the problem just by removing the definitions of fst and snd from your code, but if you absolutely want to reimplement it, it ought to look something more like this:
let fst (x, _) = x;;
let snd (_, y) = y;;
Your fst and snd functions are actually strange since you take two arguments to return the first one or the second one. I guess you wanted to get the first or second element of a pair so you should write (from most detailed to least detailed)
(* too much details *)
let fst num = match num with (x, y) -> x
let snd num = match num with (x, y) -> y
(* let's use the wildcards *)
let fst num = match num with (x, _) -> x
let snd num = match num with (_, y) -> y
(* do we really need num? *)
let fst = function (x, _) -> x
let snd = function (_, y) -> y
(* do we really need to match on a single pattern? *)
let fst (x, _) = x
let snd (_, y) = y
And it should work.
As a side note, fst and snd already exist in the standard library but it's never wrong to try implementing them yourself
Second side note, appending at the end of a list is usually not advised (not tail recursive, you're forcing the program to traverse the entire list to append an element at the end). What you could do instead is to add each new element at the head of the list and reverse the final list:
let rec dcp_base list1 list2 list3 =
match list1, list2, list3 with
| (xs, ys, []) -> (List.rev xs, List.rev ys)
| (xs, ys, z :: zs) -> dcp_base (fst z :: xs) (snd z :: ys) zs;;
And actually, since OCaml is really strong, you don't need fst and snd at all:
let rec dcp_base list1 list2 list3 =
match list1, list2, list3 with
| (xs, ys, []) -> (List.rev xs, List.rev ys)
| (xs, ys, (x, y) :: zs) -> dcp_base (x :: xs) (y :: ys) zs;;
Proof:
let rec dcp_base list1 list2 list3 =
match list1, list2, list3 with
| (xs, ys, []) -> (List.rev xs, List.rev ys)
| (xs, ys, (x, y) :: zs) -> dcp_base (x :: xs) (y :: ys) zs;;
let descompact list =
match list with
| [] -> ([], [])
| xs -> dcp_base [] [] xs;;
descompact [(1, 4); (2, 5); (3, 6)];;
- : int list * int list = ([1; 2; 3], [4; 5; 6])

Trouble with equation for tick in Wadler, »Monads for functional programming«, section 3

In Wadler's Monads for functional programming I'm looking at the equation
tick ✭ λ().m = m ✭ λ().tick
in section 3 (in the context of State Monad). It is claimed that it
holds so long as tick is the only action on state within m.
I fail to understand how this can be the case. Doesn't the left term have the type of m while the right term has the type of tick : M ()? Moreover, if the type of m isn't M (), the types of the operands of ✭ are mismatched on the right-hand side.
I looked around but couldn't find any errata, and the same equation appears in the revised version of the paper from 2001, so there must clearly be something I'm missing…
In Haskell syntax,
tick x = ((), x+1)
unitState a x = (a, x)
bindState m k = uncurry k . m -- StarOp for State
bindState tick (\() -> m) =
= uncurry (\() -> m) . (\x -> ((), x+1))
= (\y -> uncurry (\() -> m) ( (\x -> ((), x+1)) y))
= (\y -> uncurry (\() -> m) ((), y+1) )
= (\y -> (\() -> m) () (y+1) )
= (\y -> m (y+1) )
bindState m (\() -> tick) =
= uncurry (\() -> tick) . m
= uncurry (\() -> (\x -> ((), x+1))) . m
= uncurry (\() x -> ((), x+1)) . m
= (\y -> uncurry (\() x -> ((), x+1)) (m y))
= (\y -> let ((),z) = m y in ((), z+1))
These two will only be the same if m y returns ((),z) such that m (y+1) returns ((),z+1) (i.e. m y only adds some fixed amount to the initial state y, which does not depend on y).
So I don't see the problem with the types, but that English phrase's meaning eludes me too.
By the way the paper's proposed way of adding "execution counts" to its monadic evaluator by changing this unitState into unitState a x = (a, x+1), essentially, would make it an illegal monad because this new unitState won't be an identity.
The types are,
tick :: M ()
bindState :: M a -> (a -> M b) -> M b
(\() -> tick) :: () -> M ()
bindState (tick :: M ()) ((\() -> m) :: () -> M b ) :: M b
bindState (m :: M ()) ((\() -> tick) :: () -> M ()) :: M ()
So the only thing with the types is that m must be m :: M (), not the general M b, as we already saw with the expansions above.

Combine a list of functions into a single function using fold

Lets say I have a list of functions
let plus_one (x: int) : int = x + 1 in
let double (x: int) : int = x * 2 in
let square (x: int) : int = x * x in
let fun_list = [square, double, plus_one] ;;
Using fold, I want to take this list of functions and combine them into a single function. Something like,
let combined (x: int) : int = x * (2 * (x + 1))
This is what I have:
let combine_functions (fun_list : ('a -> 'a) list) : ('a -> 'a) =
List.fold_right (fun f acc -> f acc) fun_list (fun x -> x)
;;
I would think this would work, however when I try to run this, it tells me that this expression has type 'a -> 'a when it should have type ('a -> 'a) -> ('a -> 'a)
I've solved this by changing the second line of code from
List.fold_right (fun f acc -> f acc) fun_list (fun x -> x)
to
List.fold_right (fun f acc -> (fun x -> f (acc x))) fun_list (fun x -> x)
I'm a bit unclear on what sort of combination you want, do you mean functional composition? If that's the case, then your combined function would look something like this:
square (double (plus_one x))
or
((x + 1) * 2) * ((x + 1) * 2)
which could be achieved by the function
let combine_functions ls =
List.fold_right (fun f x -> f x) ls;;
However I'm not totally sure if this is really what you're trying to do. As an aside, you don't need to explicitly type all your OCaml code, and I personally find that I'm more productive when I let the type inference do it for me.

Haskell: Function using Data.Map.elems

Hi I am trying to return a value from Data.Map.Map but can't get the right value,
here is the relevant code :
data Graph v = Graph (Map.Map v [v])
edges :: Ord v => Graph v -> [(v,v)]
edges (Graph v) = Map.elems v
However this doesn't work, example of expected value : [(1,2),(1,3),(3,4)]
I get the error :
Expected type: Map.Map v (v, v) Actual type: Map.Map v [v]
elems :: Map k a -> [a] will only give you the values of the map, you probably are more interested in the assocs :: Map k a -> [(k,a)].
But if we use that, we will still not get the desired result, since this will construct a list of tuples such that we get [(v, [v])], so we need to convert every 2-tuple (x, [y1, y2, ..., yn]) into n tuples [(x, yi)]. To achieve this, we can for instance use list comprehension:
edges :: Graph v -> [(v,v)]
edges (Graph v) = [ (x, y) | (x, ys) <- Map.assocs v, y <- ys]
In case we want to order the list of edges (first by the first item of the tuples, then by the second item), we can for instance use sort :: Ord a => [a] -> [a]:
import Data.List(sort)
edges_sort :: Ord v => Graph v -> [(v,v)]
edges_sort (Graph v) = sort [ (x, y) | (x, ys) <- Map.assocs v, y <- ys]
or we can define both:
import Data.List(sort)
edges :: Graph v -> [(v,v)]
edges (Graph v) = [ (x, y) | (x, ys) <- Map.assocs v, y <- ys]
edges_sort :: Ord v => Graph v -> [(v,v)]
edges_sort = sort . edges
Some remarks:
Like #amalloy says, we can use list monads instead of list comprehension, and use sequence :: (Monad m, Traversable t) => t (m a) -> m (t a):
edges :: Graph v -> [(v,v)]
edges (Graph v) = Map.assocs v >>= sequence
Like #luqui says, we can also only sort the list of the values, since the specifications are that the keys are already sorted, so:
edges :: Graph v -> [(v,v)]
edges (Graph v) = [ (x, y) | (x, ys) <- Map.assocs v, y <- sort ys]

Resources