Recursive Haskell function but only does part of it once - function

I've got a function that needs to work out the minimum change required to break down a certain amount of money.
A user would enter a value of money and the possible denominations, and it would output how many of each denomination would be needed to make up the money eg.
> coinChange 34 [1, 5, 10, 25, 50, 100]
[4,1,0,1,0,0]
Here is what I have so far:
coinChange :: Integer -> [Integer] -> [Integer]
coinChange _ [] = []
coinChange 0 xs = []
coinChange v xs = do
dropWhile (>v) (reverse xs)
createNewList :: Integer -> [Integer]
createNewList 0 = []
createNewList x = 0 : createNewList (x - 1)
I have a separate function called createNewList which I want to call to set up a new list of 0s at the beginning.
However, because I plan on making coinChange a recursive function when working out how much money is left, if I just call makeNewList in coinChange, at the moment it would reset the list because it would be called every recursion.
So my question is, is there a way to make a function call another function only once, before proceeding with the recursion.
Hope I've made it clear, thanks

In general you are allowed to create local helper functions in Haskell. Maybe this example will inspire you:
prepareData x = if x < 0 then -x else x
mainFunction n =
let recursiveLocalFunction x =
if x < 2 then 1 else x * recursiveLocalFunction (x - 1)
in recursiveLocalFunction (prepareData n)

Related

Ocaml function, what is the nature of the problem?

Currently i'm trying
I have a function to calculate the inverse sum of a number
let inverseSum n =
let rec sI n acc =
match n with
| 1 -> acc
| _ -> sI (n - 1) ((1.0 /. float n) +. acc)
in sI n 1.0;;
For example, inverseSum 2 -> 1/2 + 1 = 3/2 = 1.5
I try to test the function with 2 and 5, it's okay:
inverseSum 2;;
inverseSum 5;;
inverseSum 2;;
- : float = 1.5
inverseSum 5;;
- : float = 2.28333333333333321
For the moment, no problem.
After that, I initialize a list which contains all numbers between 1 and 10000 ([1;…;10000])
let initList = List.init 10000 (fun n -> n + 1);;
no problem.
I code a function so that an element of the list becomes the inverse sum of the element
(e.g. [1;2;3] -> [inverseSum 1; inverseSum 2; inverseSum 3])
let rec invSumLst lst =
match lst with
| [] -> []
| h::t -> (inverseSum h) :: invSumLst t;;
and I use it on the list initList:
let invInit = invSumLst initList;;
So far so good, but I start to have doubts from this stage:
I select the elements of invList strictly inferior to 5.0
let listLess5 = List.filter (fun n -> n < 5.0) invInit;;
And I realize the sum of these elements using fold_left:
let foldLess5 = List.fold_left (+.) 0.0 listLess5;;
I redo the last two steps with floats greater than or equal to 5.0
let moreEg5 = List.filter (fun n -> n >= 5.0) invInit;;
let foldMore5 = List.fold_left (+.) 0.0 moreEg5;;
Finally, I sum all the numbers of the list:
let foldInvInit = List.fold_left (+.) 0.0 invInit;;
but at the end when I try to calculate the absolute error between the numbers less than 5, those greater than 5 and all the elements of the list, the result is surprising:
Float.abs ((foldLess5 +. foldMore5) -. foldInvInit);;
Printf.printf "%f\n" (Float.abs ((foldLess5 +. foldMore5) -. foldInvInit));;
Printf.printf "%b\n" ((foldLess5+.foldMore5) = foldInvInit);;
returns:
let foldMore5 = List.fold_left (+.) 0.0 moreEg5;;
val foldMore5 : float = 87553.6762998474733
let foldInvInit = List.fold_left (+.) 0.0 invInit;;
val foldInvInit : float = 87885.8479664799379
Float.abs ((foldLess5 +. foldMore5) -. foldInvInit);;
- : float = 1.45519152283668518e-11
Printf.printf "%f\n" (Float.abs ((foldLess5 +. foldMore5) -. foldInvInit));;
0.000000
- : unit = ()
Printf.printf "%b\n" ((foldLess5+.foldMore5) = foldInvInit);;
false
- : unit = ()
it's probably a rounding problem, but I would like to know where exactly the error comes from?
Because here I am using an interpreter, so I see the error "1.45519152283668518e-11"
But if I used a compiler like ocamlpro, I would just get 0.000000 and false on the terminal and I wouldn't understand anything.
So I would just like to know if the problem comes from one of the functions of the code, or from a rounding made by the Printf.printf function which wrote the result with a "non scientific" notation.
OCaml is showing you the actual results of the operations you performed. The difference between the two sums is caused by the finite precision of floating values.
When adding up a list of large-ish numbers, by the time you reach the end of the list the number is large enough that the lowest-order bits of the new values simply can't be represented. But when adding a list of small-ish numbers, fewer bits are lost.
A system that shows foldLess5 +. foldMore5 as equal to foldInvInit is most likely lying to you for your convenience.

Loop a function 10 times in Haskell

Do you have any idea how I can loop the function func2 10 times
type Vertex = Int
type OutNeighbors = [Vertex]
data Graph = Graph [(Vertex,OutNeighbors)] deriving (Eq, Show, Read)
func2 (Graph g) = filter (\x -> contains (fst x) (func1 (Graph g))) g --I need to repeat this function 10 times.
I am kind of new to haskell and I have no idea how to do loops
Do you have any idea how I can loop the function func2 10 times
You could iterate it and !! at 10:
> take 5 $ iterate ("hi " ++) "there!"
["there!","hi there!","hi hi there!","hi hi hi there!","hi hi hi hi there!"]
> let func2 = (+3) in iterate func2 0 !! 10
30
but that would require func2 to return the same type as its input, and right now it appears to have type
func2 :: Graph -> [(Vertex,OutNeighbors)]
But if you wrapped Graph back onto it, i.e.,
func2 :: Graph -> Graph
func2 (Graph g) = Graph (... g)
then you could iterate on it.
In Haskell you can use recursion for loops, here is an example:
myLoop 0 g = g
myLoop n g = myLoop (n - 1) (Graph (func2 g))
Now calling myLoop 10 g will call func2 10 times on g.
Note that I had to wrap the result back in the Graph type, that is probably something you should do in the func2 function:
func2 (Graph g) = Graph (filter (\x -> contains (fst x) (func1 (Graph g))) g)
You can get a little bit higher-level if you wrap this up in the State monad from the transformers package:
import Control.Monad.Trans.State.Lazy (execState, modify)
import Control.Monad (replicateM_)
myLoop :: Int -> Graph -> Graph
myLoop n g = execState (replicateM_ n (modify func2)) g
This is one of these situations where, in order to avoid typing errors, you need to be able to refer to both the whole parameter and to its subcomponents thru proper names.
Fortunately, Haskell provides just that. This is known as the “as patterns”. More details here: SO-q30326249.
In your case, you could note your graph parameter as: g#(Graph(pairs)). Then, g is your graph object, and pairs is the corresponding list of type [(Vertex,OutNeighbors)].
You do not tell us about your contains function, but it is possible to infer that its type is:
contains :: Vertex -> Graph -> Bool
With that in mind, a version of your graph function taking an arbitrary iteration count can be written this way:
type Vertex = Int
type OutNeighbors = [Vertex]
data Graph = Graph [(Vertex,OutNeighbors)] deriving (Eq, Show, Read)
funcN :: Int -> Graph -> Graph
funcN iterCount g#(Graph(pairs)) =
if (iterCount <= 0) then g -- nothing to do
else let
gm1 = funcN (iterCount - 1) g -- recursion
fn = \(v,ngs) -> contains v gm1 -- filtration
in
Graph (filter fn pairs)
Using the same techniques, a tentative version of the contains function could be like this:
contains :: Vertex -> Graph -> Bool
contains v g#( Graph [] ) = False
contains v g#( Graph ((v0,ngs0):pairs) ) = (v == v0) || contains v (Graph(pairs))
This second function is a bit more complicated, because lists can be described thru 2 patterns, empty and non-empty.
Finally, a version of the function that does exactly 10 iterations can be written like this:
func10 :: Graph -> Graph
func10 g = funcN 10 g
or also in a more concise fashion using partial application (known in Haskell circles as currying):
func10 :: Graph -> Graph
func10 = funcN 10
Addendum: library style, using nest:
If for some reason “manual recursion” is frowned upon, it is possible to use instead the nest :: Int -> (a -> a) -> a -> a library function. It computes the Nth compositional power of a function, using recursion internally.
Then one just has to write the single iteration version of the graph function. The code looks like this:
import Data.Function.HT (nest)
funcNl :: Int -> Graph -> Graph
funcNl iterCount g0 = let
-- 2 local function definitions:
ftfn g1 (v, ngs) = contains v g1
func1 g2#(Graph(pairs)) = Graph (filter (ftfn g2) pairs)
in
nest iterCount func1 g0

What's wrong with this recursive curried function

I was trying to write a function that solves following;
persistence 39 = 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit
persistence 999 = 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2
persistence 4 = 0 // because 4 is already a one-digit number
After I solved the question I tried to make all functions looks like Ramda.js function styles like this;
This code works;
let multiply = List.reduce (*)
let gt from input = input > from
let just input = fun _ -> input
let ifElse cond trueFn falseFn input =
if cond input then trueFn input else falseFn input
let digits n =
(string n) |> Seq.toList |> List.map (System.Char.GetNumericValue >> int)
let rec persRec iter current =
current
|> digits
|> multiply
|> ifElse (gt 9) (persRec (iter + 1)) (just iter)
let persistence n = if n > 9 then persRec 1 n else 0
But when I tried to modify persRec function with a curried composed version like following, it makes this stack overflow.
let rec persRec iter =
digits
>> multiply
>> ifElse (gt 9) (persRec (iter + 1)) (just iter)
What's wrong with this?
The function persRec is calling itself unconditionally. Here:
>> ifElse (gt 9) (persRec (iter + 1)) (just iter)
^^^^^^^^^^^^^^^^^^^^
|
unconditional recursive call
This happens always. Every time persRec is called by somebody, it immediately calls itself right away.
You may expect that the recursive call should only happen when gt 9, because, after all, it's inside an ifElse, right? But that doesn't matter: ifElse is not special, it's just a function. In order to call a function, F# has to compute all its parameter before the call (aka "applicative order of evaluation"), which means it has to call persRec (iter + 1) before it can call ifElse, and it has to call ifElse before it can call (>>), and it has to call (>>) in order to compute result of persRec. So ultimately, it needs to call persRec in order to compute the result of persRec. See where this is going?
The previous version works, because the body of persRec is not actually executed before the call to ifElse. The body of persRec will only be executed when all its parameters are supplied, and the last parameter will only be supplied inside the body of ifElse when the condition is true.
The way I see it, the confusion stems from the difference between denotational and operational semantics. Yes, mathematically, logically, the functions are equivalent. But execution also matters. Normal vs. applicative evaluation order. Memory concerns. Performance. Those are all outside of the domain of lambda-calculus.

Binary to Decimal Conversion in Haskell using Horners Algorithm

I am trying to implement a function here which takes a list of Bool representing binary numbers such as [True, False, False] and convert that into corresponding decimal number according to Horners method.
Function type would be [Bool] -> Int.
Algorithms which i am following is:
Horners Algorithm Visual Explanation:
So far i have implemented the logic in which it says first it will check whether the list is empty or either one element in the list [True], will give 1 and [False] will give 0.
Then in this case binToDecList (x:xs) = binToDecList' x 0 what i did to treat first element whether this is True or False.
binToDecList :: [Bool] -> Int
binToDecList [] = error "Empty List"
binToDecList [True] = 1
binToDecList [False] = 0
binToDecList (x:xs) = binToDecList' x 0
binToDecList' x d | x == True = mul (add d 1)
| otherwise = mul (add d 0)
add :: Int -> Int -> Int
add x y = x + y
mul :: Int -> Int
mul x = x * 2
I want to use the result of binToDecList' in the next iteration calling itself recursively on the next element of the list. How can i store the result and then apply it to next element of the list recursively. Any kind of help would be appreciated.
The type* of foldl tells us how it must work.
foldl :: (b -> a -> b) -> b -> [a] -> b
Clearly [a], the third argument that is a list of something, must be the list of Bool to be handed to Horner’s algorithm. That means the type variable a must be Bool.
The type variable b represents a possibly distinct type. We are trying to convert [Bool] to Int, so Int is a decent guess for b.
foldl works by chewing through a list from the left (i.e., starting with its head) and somehow combining the result so far with the next element from the list. The second argument is typically named z for “zero” or the seed value for the folding process. When foldl reaches the end of the list, it returns the accumulated value.
We can see syntactically that the first argument is some function that performs some operation on items of type b and type a to yield a b. Now, a function that ignores the a item and unconditionally results in whatever the b is would fit but wouldn’t be very interesting.
Think about how Horner’s algorithm proceeds. The numbers at the elbows of the path on your diagram represent the notional “result so far” from the previous paragraph. We know that b is Int and a is Bool, so the function passed to foldl must convert the Bool to Int and combine it with the result.
The first step in Horner’s algorithm seems to be a special case that needs to be handled differently, but foldl uses the same function all the way through. If you imagine “priming the pump” with an invisible horizontal move (i.e., multiplying by two) to begin with, we can make the types fit together like puzzle pieces. It’s fine because two times zero is still zero.
Thus, in terms of foldl, Horner’s algorithm is
horners :: [Bool] -> Int
horners = foldl f 0
where f x b =
let b' = fromEnum b
in 2*x + b'
Notice that 2*x + b' combines subsequent horizontal and vertical moves.
This also suggests how to express it in direct recursion.
horners' :: [Bool] -> Int
horners' [] = 0
horners' l = go 0 l
where -- over then down
go x [] = x
go x (b:bs) =
let b' = fromEnum b
in go (2*x + b') bs
Here the inner go loop is performing the left-fold and combining each next Bool with the result so far in i.
* A pedagogical simplification: the actual type generalizes the list type into Foldable.

OCaml and creating a list of lists

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