I found the following piece of code in Contract.hs line 147 Pricing Financial Contracts with Haskell:
konstSlices :: a -> [[a]]
konstSlices x = nextSlice [x]
where nextSlice sl = sl : nextSlice (x:sl)
This produces a infinite list of lists:
konstSlices 100 = [[100],[100,100],[100,100,100],...]
I am not sure what is happening inside the where clause. If we just take 3 iterations what should be inside the nextSlice at this time
[100]:[100,100]:nextSlice (100 :[100,100]) ?
how the terminating: [] appears to pack the lists inside a list [100]:[100,100]:[100,100,100]:[] = [[100],[100,100],[100,100,100]]
the recursive construction is really hard to follow btw I am curious if there are tools allowing to follow such iterations and see how such values are build? Actually in such cases I am using a pen and a paper to get a grip on what is hapenning. Recursion lists are not the worst case btw.. (what bring me to this question was the analysis of the function at t (line 130) with the liftA2'ing stuff inside applicative functions which are build from other smaller functions or data constructor with function type, you rapidly see growing a big chunk of inter-related computations and you are totally lost - brain washed..)
Here is a much simpler case for you
Prelude> let ones = 1 : ones
Prelude> take 3 ones
[1,1,1]
ones is defined to be an infinite list of 1s. There is no end, so there is no final empty list constructor. take n initiates the generation of the first n elements, here with n=3.
karakfa has a great illustration of what’s going on here, but I’ll expand a bit.
There isn’t any closing ]. A list is a data structure whose head is an item of data, and whose tail is a list. Furthermore, objects in Haskell are lazily evaluated.
Let’s take another look at this example:
konstSlices :: a -> [[a]]
konstSlices x = nextSlice [x]
where nextSlice sl = sl : nextSlice (x:sl)
Lazy evaluation means that, if you try to use konstSlices 100, the program will only calculate as many items of the list as it needs to. So, if you take 1 (konstSlices 100), the program will compute
konstSlices 100 = [100]:
nextSlice (100:[100]))
The tail of the list, everything after the [100]:, is stored as a thunk. Its value hasn’t been computed yet.
What if you ask for take 2 (konstSlices 100)? Then, the program needs to compute the thunk until it finds the second element. That’s all it needs, so it will stop when it gets to,
konstSlices 100 = [100]:
[100,100]:
(nextSlice (100:[100,100]))
And so on, for however many entries you need to compute.
There’s never anything corresponding to a closing bracket. There doesn’t need to be. The recursive definition of konstSlices never generates anything like one, just more thunks. And that’s allowed.
On the other hand, if you try to take length (konstSlices 100), the program will attempt to generate an infinite number of nodes, run out of memory, and crash. If you tried to compute the entirety of a circular list, like xs = 1:xs, it wouldn’t need to allocate any new nodes, because it links back to the same ones, and it wouldn’t need to generate new stack frames, because it’s tail-recursive modulo cons, so it would go into an infinite loop.
the logic is very simple
konstSlices :: a -> [[a]]
konstSlices x = nextSlice [x]
where nextSlice sl = sl : nextSlice (x:sl)
if x = 100 then nextSlice will return [100] then it will recursive get first element and append it to the previous list nextSlice (x:sl) in this case sl will grow with each call , sorted by list index
0 -> [100] = [100]
1 -> [100,100] = nextSlice (100:[100])
2 -> [100 ,100,100] = nextSlice (100:[100 ,100])
3 -> [100 ,100 , 100,100] = nextSlice (100:[100 , 100,100])
and process will continue ,
x:sl the first element of sl list is x.
and every nextSlice call will return a list. sl:sl:sl ...
same as this one where acc = 1
num = 100 : num
slice acc = take acc num :slice (acc+1)
Your code is meant to be instructional.
The list with one value prepended is displayed every iteration so that you get
[100]
[100,100]
[100,100,100]
however many times you want it. Every list listed is a brand new list. Haskell builds a new list every iteration by prepending one value to the previous list. The use of a previous value in the next value is what recursive functions do. See below, the first example.
In an actual program, you might not be interested in the building of a list but only in the final result.
Haskell has functions that help you see your list as it is being built. The functions generalize primitive recursion and so can work with 90% of all recursive functions that you may need.
The functions are foldl/foldr and scanl/scanr. When you want to see your list being built use scan?. When you want just the final result use fold?.
You may only be interested in the construction as in the following to build a Fibonacci list up to 12.
scanl (\(a,b) x -> (a+b,a)) (1,0) [2..12]
[(1,0),(1,1),(2,1),(3,2),(5,3),(8,5),(13,8),(21,13),(34,21),(55,34),(89,55),(144,89)]
in which the previous two values are added to make the next first value and the previous first value becomes the next second value.
In your code with 3 iterations, you can see what happens to each, easily.
take 3.konstSlices $ 100
[ [100], [100,100], [100,100,100] ]
scanl (\b a -> a : b) [] $ take 3 $ repeat 100
[ [], [100], [100,100], [100,100,100] ]
But this shows more. It has the initial null list value to which it prepends 100 to, for the next value.
If you want only the final result,
foldl (\b a -> a : b) [] $ take 3 $ repeat 100
[100,100,100]
It is exactly
100 : [] = [100]
100 : [100] = [100,100]
100 : [100,100] = [100,100,100]
Related
I was trying to implement permutation to cycles in Haskell without using Monad. The problem is as follow: given a permutation of numbers [1..n], output the correspondence disjoint cycles. The function is defined like
permToCycles :: [Int] -> [[Int]]
For the input:
permToCycles [3,5,4,1,2]
The output should be
[[3,4,1],[5,2]]
By the definition of cyclic permutation, the algorithm itself is straightforward. Since [3,5,4,1,2] is a permutation of [1,2,3,4,5], we start from the first element 3 and follow the orbit until we get back to 3. In this example, we have two cycles 3 -> 4 -> 1 -> 3. Continue to do so until we traverse all elements. Thus the output is [[3,4,1],[5,2]].
Using this idea, it is fairly easy to implement in any imperative language, but I have trouble with doing it in Haskell. I find something similar in the module Math.Combinat.Permutations, but the implementation of function permutationToDisjointCycles uses Monad, which is not easy to understand as I'm a beginner.
I was wondering if I could implement it without Monad. Any help is appreciated.
UPDATE: Here is the function implemented in Python.
def permToCycles(perm):
pi_dict = {i+1: perm[i]
for i in range(len(perm))} # permutation as a dictionary
cycles = []
while pi_dict:
first_index = next(iter(pi_dict)) # take the first key
this_elem = pi_dict[first_index] # the first element in perm
next_elem = pi_dict[this_elem] # next element according to the orbit
cycle = []
while True:
cycle.append(this_elem)
# delete the item in the dict when adding to cycle
del pi_dict[this_elem]
this_elem = next_elem
if next_elem in pi_dict:
# continue the cycle
next_elem = pi_dict[next_elem]
else:
# end the cycle
break
cycles.append(cycle)
return cycles
print(permToCycles([3, 5, 4, 1, 2]))
The output is
[[3,4,1],[5,2]]
I think the main obstacle when implementing it in Haskell is how to trace the marked (or unmarked) elements. In Python, it can easily be done using a dictionary as I showed above. Also in functional programming, we tend to use recursion to replace loops, but here I have trouble with thinking the recursive structure of this problem.
Let's start with the basics. You hopefully started with something like this:
permutationToDisjointCycles :: [Int] -> [[Int]]
permutationToDisjointCycles perm = ...
We don't actually want to recur on the input list so much as we want to use an index counter. In this case, we'll want a recursive helper function, and the next step is to just go ahead and call it, providing whatever arguments you think you'll need. How about something like this:
permutationToDisjointCycles perm = cycles [] 0
where
cycles :: [Int] -> Int -> [[Int]]
cycles seen ix = ...
Instead of declaring a pi_dict variable like in Python, we'll start with a seen list as an argument (I flipped it around to keeping track of what's been seen because that ends up being a little easier). We do the same with the counting index, which I here called ix. Let's consider the cases:
cycles seen ix
| ix >= length perm = -- we've reached the end of the list
| ix `elem` seen = -- we've already seen this index
| otherwise = -- we need to generate a cycle.
That last case is the interesting one and corresponds to the inner while loop of the Python code. Another while loop means, you guessed it, more recursion! Let's make up another function that we think will be useful, passing along as arguments what would have been variables in Python:
| otherwise = let c = makeCycle ix ix in c : cycles (c ++ seen) (ix+1)
makeCycle :: Int -> Int -> [Int]
makeCycle startIx currentIx = ...
Because it's recursive, we'll need a base case and recursive case (which corresponds to the if statement in the Python code which either breaks the loop or continues it). Rather than use the seen list, it's a little simpler to just check if the next element equals the starting index:
makeCycle startIx currentIx =
if next == start
then -- base case
else -- recursive call, where we attach an index onto the cycle and recur
where next = perm !! i
I left a couple holes that need to be filled in as an exercise, and this version works on 0-indexed lists rather than 1-indexed ones like your example, but the general shape of the algorithm is there.
As a side note, the above algorithm is not super efficient. It uses lists for both the input list and the "seen" list, and lookups in lists are always O(n) time. One very simple performance improvement is to immediately convert the input list perm into an array/vector, which has constant time lookups, and then use that instead of perm !! i at the end.
The next improvement is to change the "seen" list into something more efficient. To match the idea of your Python code, you could change it to a Set (or even a HashSet), which has logarithmic time lookups (or constant with a hashset).
The code you found Math.Combinat.Permutations actually uses an array of Booleans for the "seen" list, and then uses the ST monad to do imperative-like mutation on that array. This is probably even faster than using Set or HashSet, but as you yourself could tell, readability of the code suffers a bit.
I have the following function, which counts number of differences between two strings:
distance1 :: String -> String -> Int
distance1 list1 list2 = length . filter (uncurry (/=)) $ zip list1 list2
It works just fine. Can work on any size lists within constant space.
I also was playing around with - let's say - low level, recursion-based, not-good implementation for this function and had the following:
distance2 :: String -> String -> Int
distance2 list1 list2 = distanceHelper 0 0
where
distanceHelper index result
| index == length list1 = result
| otherwise = distanceHelper (index + 1) (result + diff)
where
char1 = list1 !! index
char2 = list2 !! index
diff = if char1 /= char2 then 1 else 0
I know accessing by index for linked list is terrible, but here I'm not worrying about time, but about space. Since it is tail recursive, I expect it also to run for any size list within constant space.
The following is the program used to test:
main :: IO ()
main = print $ distance2 list1 list2
where
list1 = replicate count 'A'
list2 = replicate count 'B'
count = 100000000
If I'll run the one with distance1 and for any size (e.g. 100000000000000000), yes, it will be running for a very long time, but it will eat about 3-4 MB and do the job anyway.
If I'll run test with distance2 (just with 100000000), it will immediately eat a lot of memory (about 1G), but then will stop eating memory and continue to do the job without consuming more memory. So it makes impression it also runs for constant space, but that space is too much.
I would like to understand why exactly the second version takes so much memory?
Note: just in case tried second version with bang patterns, i.e. declared inner function as distanceHelper !index !result, but that didn't help.
I know accessing by index for linked list is terrible, but here I'm not worrying about time, but about space. Since it is tail recursive, I expect it also to run for any size list within constant space.
No, that's precisely the issue here.
If a list is generated with replicate count 'A', it can be generated lazily. If we access the first element, discard it, then the second one, discard it, and so on, the computation can be performed in constant space, since elements can be garbage collected quickly after they are discarded. This requires the consumer to be something like
consume [] = ...
consume (x:xs) = .... (consume xs) -- x was used and then discarded
If we instead use !! to access the list, the compiler can no longer discard the list elements. After all, we could later on request with !! an element we used a long time ago. Hence, the full list of count elements must be stored in memory.
Now, a very smart compiler might perform a static analysis and prove that the indices used in !! are strictly increasing, and we can indeed discard/garbage collect the prefix of the list. Most compilers are not that smart, though.
Further, length is also used here:
distanceHelper index result
| index == length list1 = result
...
length list1 will work in constant space if it can consume list1, i.e. if list1 is no longer used afterwards. This is not the case, so that will force the full list to be generated and kept in memory, using count cells. Yet another reason why we should avoid length and !!.
To stress the point above:
let list = replicate count 'A'
in length list
should be constant space, while
let list = replicate count 'A'
in length list + length list
can not be (barring very smart optimizations), since we can not consume list for the first length call -- we need it for the second call later on.
Even more subtly,
let list () = replicate count 'A'
in length (list ()) + length (list ())
will work in constant space, since the result of function calls is not cached. Above, we generate (and consume) the list twice, and this can be done in constant space.
i was given a homework in Haskell in which i should program a module, which helps detect prime numbers from a list, say :
[2,3,4,5,6,7,8,9,10]
For the homework, I should iterate through every elements of this list, and eliminate all of it's multiples. Example, I go at number 2, I should eliminate 4,6,8,10. Then go to number 3 and delete 6 and 9, and so on until the end, return the list with prime numbers only.
I have an idea of using function map, but I'm stuck at this place (I'm pretty new to Haskell, though)
Yes, it is my homework, but no, i don't have to do it, it's just practicing. So I'm thankful for any help.
Instead of using a map (I don't think that's possible without doing some pre-processing), you can roll your own function:
sieveWith _ [] = []
sieveWith ss (x:xs) | any ((==) 0 . mod x) ss = sieveWith ss xs
| otherwise = x : (sieveWith (x:ss) xs)
and:
sieve = sieveWith []
Now if you call sieve:
*Main> sieve [2,3,4,5,6,7,8,9,10]
[2,3,5,7]
The function works with a variable (the first one) that is passed through the function calls and each time a value is picked, added to the list. A value is picked if no modulo operation on the variable list yields a zero (second guard). In case any of the modulo's yields zero, the value is simply omitted.
I'm a new student and I'm studying in Computer Sciences. We're tackling Haskell, and while I understand the idea of Haskell, I just can't seem to figure out how exactly the piece of code we're supposed to look at works:
module U1 where
double x = x + x
doubles (d:ds) = (double d):(doubles ds)
ds = doubles [1..]
I admit, it seems rather simple for someone that knows whats happening, but I can't wrap my head around it. If I write "take 5 ds", it obviously gives back [2,4,6,8,10]. What I dont get, is why.
Here's my train of thought : I call ds, which then looks for doubles. because I also submit the value [1..], doubles (d:ds) should mean that d = 1 and ds = [2..], correct? I then double the d, which returns 2 and puts it at the start of a list (array?). Then it calls upon itself, transferring ds = [2..] to d = 2 and ds = [3..], which then doubles d again and again calls upon itself and so on and so forth until it can return 5 values, [2,4,6,8,10].
So first of all, is my understanding right? Do I have any grave mistakes in my string of thought?
Second of all, since it seems to save all doubled d into a list to call for later, whats the name of that list? Where did I exactly define it?
Thanks in advance, hope you can help out a student to understand this x)
I think you are right about the recursion/loop part about how doubles goes through each element of the infinite list.
Now regarding
it seems to save all doubled d into a list to call for later, whats
the name of that list? Where did I exactly define it?
This relates to a feature that's called Lazy Evaluation in Haskell. The list isn't precomputed and stored any where. Instead, you can imagine that a list is a function object in C++ that can generate elements when needed. (The normal language you may see is that expressions are evaluated on demand). So when you do
take 5 [1..]
[1..] can be viewed as a function object that generates numbers when used with head, take etc. So,
take 5 [1..] == (1 : take 4 [2..])
Here [2..] is also a "function object" that gives you numbers. Similarly, you can have
take 5 [1..] == (1 : 2 : take 3 [3..]) == ... (1 : 2 : 3 : 4 : 5 : take 0 [6..])
Now, we don't need to care about [6..], because take 0 xs for any xs is []. Therefore, we can have
take 5 [1..] == (1 : 2 : 3 : 4 : 5 : [])
without needing to store any of the "infinite" lists like [2..]. They may be viewed as function objects/generators if you want to get an idea of how Lazy computation can actually happen.
Your train of thought looks correct. The only minor inaccuracy in it lies in describing the computation using expressions such has "it doubles 2 and then calls itself ...". In pure functional programming languages, such as Haskell, there actually is no fixed evaluation order. Specifically, in
double 1 : double [2..]
it is left unspecified whether doubling 1 happens before of after doubling the rest of the list. Theoretical results guarantee that order is indeed immaterial, in that -- roughly -- even if you evaluate your expression in a different order you will get the same result. I would recommend that you see this property at work using the Lambda Bubble Pop website: there you can pop bubbles in a different order to simulate any evaluation order. No matter what you do, you will get the same result.
Note that, because evaluation order does not matter, the Haskell compiler is free to choose any evaluation order it deems to be the most appropriate for your code. For instance, let ds be defined as in the final line in your code, and consider
take 5 (drop 5 ds)
this results in [12,14,16,18,20]. Note that the compiler has no need to double the first 5 numbers, since you are dropping them, so they can be dropped before they are completely computed (!!).
If you want to experiment, define yourself a function which is very expensive to compute (say, write fibonacci following the recursive definifion).
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci n = fibonacci (n-1) + fibonacci (n-2)
Then, define
const5 n = 5
and compute
fibonacci 100
and observe how long that actually takes. Then, evaluate
const5 (fibonacci 100)
and see that the result is immediately reached -- the argument was not even computed (!) since there was no need for it.
I am very bad at wording things, so please bear with me.
I am doing a problem that requires me to generate all possible numbers in the form of a lists of lists, in Haskell.
For example if I have x = 3 and y = 2, I have to generate a list of lists like this:
[[1,1,1], [1,2,1], [2,1,1], [2,2,1], [1,1,2], [1,2,2], [2,1,2], [2,2,2]]
x and y are passed into the function and it has to work with any nonzero positive integers x and y.
I am completely lost and have no idea how to even begin.
For anyone kind enough to help me, please try to keep any math-heavy explanations as easy to understand as possible. I am really not good at math.
Assuming that this is homework, I'll give you the part of the answer, and show you how I think through this sort of problem. It's helpful to experiment in GHCi, and build up the pieces we need. One thing we need is to be able to generate a list of numbers from 1 through y. Suppose y is 7. Then:
λ> [1..7]
[1,2,3,4,5,6,7]
But as you'll see in a moment, what we really need is not a simple list, but a list of lists that we can build on. Like this:
λ> map (:[]) [1..7]
[[1],[2],[3],[4],[5],[6],[7]]
This basically says to take each element in the array, and prepend it to the empty list []. So now we can write a function to do this for us.
makeListOfLists y = map (:[]) [1..y]
Next, we need a way to prepend a new element to every element in a list of lists. Something like this:
λ> map (99:) [[1],[2],[3],[4],[5],[6],[7]]
[[99,1],[99,2],[99,3],[99,4],[99,5],[99,6],[99,7]]
(I used 99 here instead of, say, 1, so that you can easily see where the numbers come from.) So we could write a function to do that:
prepend x yss = map (x:) yss
Ultimately, we want to be able to take a list and a list of lists, and invoke prepend on every element in the list to every element in the list of lists. We can do that using the map function again. But as it turns out, it will be a little easier to do that if we switch the order of the arguments to prepend, like this:
prepend2 yss x = map (x:) yss
Then we can do something like this:
λ> map (prepend2 [[1],[2],[3],[4],[5],[6],[7]]) [97,98,99]
[[[97,1],[97,2],[97,3],[97,4],[97,5],[97,6],[97,7]],[[98,1],[98,2],[98,3],[98,4],[98,5],[98,6],[98,7]],[[99,1],[99,2],[99,3],[99,4],[99,5],[99,6],[99,7]]]
So now we can write that function:
supermap xs yss = map (prepend2 yss) xs
Using your example, if x=2 and y=3, then the answer we need is:
λ> let yss = makeListOfLists 3
λ> supermap [1..3] yss
[[[1,1],[1,2],[1,3]],[[2,1],[2,2],[2,3]],[[3,1],[3,2],[3,3]]]
(If that was all we needed, we could have done this more easily using a list comprehension. But since we need to be able to do this for an arbitrary x, a list comprehension won't work.)
Hopefully you can take it from here, and extend it to arbitrary x.
For the specific x, as already mentioned, the list comprehension would do the trick, assuming that x equals 3, one would write the following:
generate y = [[a,b,c] | a<-[1..y], b<-[1..y], c <-[1..y]]
But life gets much more complicated when x is not predetermined. I don't have much experience of programming in Haskell, I'm not acquainted with library functions and my approach is far from being the most efficient solution, so don't judge it too harshly.
My solution consists of two functions:
strip [] = []
strip (h:t) = h ++ strip t
populate y 2 = strip( map (\a-> map (:a:[]) [1..y]) [1..y])
populate y x = strip( map (\a-> map (:a) [1..y]) ( populate y ( x - 1) ))
strip is defined for the nested lists. By merging the list-items it reduces the hierarchy so to speak. For example calling
strip [[1],[2],[3]]
generates the output:
[1,2,3]
populate is the tricky one.
On the last step of the recursion, when the second argument equals to 2, the function maps each item of [1..y] with every element of the same list into a new list. For example
map (\a-> map (:a:[]) [1..2]) [1..2])
generates the output:
[[[1,1],[2,1]],[[1,2],[2,2]]]
and the strip function turns it into:
[[1,1],[2,1],[1,2],[2,2]]
As for the initial step of the recursion, when x is more than 2, populate does almost the same thing except this time it maps the items of the list with the list generated by the recursive call. And Finally:
populate 2 3
gives us the desired result:
[[1,1,1],[2,1,1],[1,2,1],[2,2,1],[1,1,2],[2,1,2],[1,2,2],[2,2,2]]
As I mentioned above, this approach is neither the most efficient nor the most readable one, but I think it solves the problem. In fact, theoritically the only way of solving this without the heavy usage of recursion would be building the string with list comprehension statement in it and than compiling that string dynamically, which, according to my short experience, as a programmer, is never a good solution.