I am working on a programming exercise where the goal is to write a function to get the term at the Nth index of Hofstadter's Figure-Figure sequence.
Rather come up with a basic solution using the formula, I thought it would be an interesting challenge to generate an infinite list to represent the sequence and then index it.
This was my initial approach, however, it hangs when trying to calculate anything past the first two terms.
hof :: Int -> Int
hof = (!!) seqA
where
seqA = 1 : zipWith (+) seqA seqB
seqB = 2 : filter (`notElem` seqA) [3..]
seqA represents the sequence of terms, and seqB is the differences between them.
Though I don't really understand how to use seq, I tried using it to strictly evaluate the terms that come before the desired one, like shown below.
hof :: Int -> Int
hof 0 = 1
hof n = seq (hof $ n - 1) $ seqA !! n
where
seqA = 1 : zipWith (+) seqA seqB
seqB = 2 : filter (`notElem` seqA) [3..]
This also hangs when trying to calculate values past the first index.
After playing around in ghci, I found a way to get this to work in a weird way
ghci> seqB = [2, 4, 5, 6]
ghci> seqA = 1 : zipWith (+) seqA seqB
ghci> seqB = 2 : filter (`notElem` seqA) [3..]
ghci> seqA = 1 : zipWith (+) seqA seqB
ghci> hof = (!!) seqA
By giving seqB and initial value and redefining both seqA and seqB afterwards, it seems to function normally. I did notice, however, that the result of passing larger values to hof seems to give different results based on how many terms I initially put in the seqB list. When I redefine the function in ghci, does it still use the older version for functions that call it previous to its redefinition?
I would like to know why this works in ghci and whether it's possible to write a working version of this code using a similar technique. Thanks in advance!
The problem is that seqA is infinite, and so
(`notElem` seqA) x
can never return True. If it sees that x is the first element of seqA, then great: it can return False. But if it doesn't see x, it wants to keep looking: maybe x is the next element! The list never ends, so there's no way it can conclude x is definitely not present.
This is a classic mistake beginners make, trying to filter an infinite list and expecting the list to end at some point. Often, the answer is to use something like
x `notElem` (takeWhile (<= x) infList)
instead. This way, your program gives up on searching for x once it's found a number above x. This only works if your lists are sorted, of course. Your equations look like they probably produce ascending lists, in which case it would work, but I haven't worked through the algebra. If your lists aren't in ascending order, you'll need to design some other stopping condition to avoid the infinite recursion.
The other answer tells you the problem with your approach, and suggests a great fix. I thought it might be fun to try to work out a slightly more efficient solution, though; it seems a shame to keep checking the beginning of seqA over and over during our membership calls. Here's the idea I had: the point is for seqB to be the complement of seqA, right? Well, what if we just directly define a complement function? Like this:
complement :: Integer -> [Integer] -> [Integer]
complement = go 1 where
go i xs#(x:xt) = case compare i x of
LT -> i : go (i+1) xs
EQ -> i+1 : go (i+2) xt
GT -> go i xt -- this case should be impossible
go i [] = [i..] -- this case is irrelevant for our purposes
The EQ case is a bit suspect; it doesn't work for general increasing input sequences. (But see below.) Anyway, with this definition in place, the two sequences can be quite naturally defined:
seqA, seqB :: [Integer]
seqA = 1 : zipWith (+) seqA seqB
seqB = complement seqA
Try it in ghci:
> take 10 seqA
[1,3,7,12,18,26,35,45,56,69]
Nice. Now, if we fix up the EQ case to work properly for all (increasing) input sequences, it would have to look like this:
complement :: Integer -> [Integer] -> [Integer]
complement = go i where
go i xs#(x:xt) = case compare i x of
LT -> i : go (i+1) xs
EQ -> go (i+1) xt
GT -> go i xt -- still impossible
go i [] = [i..] -- still irrelevant
Unfortunately, our definitions of seqA and seqB above don't quite work any more. The right first value for seqB depends on whether 2 is in seqA, but whether 2 is in seqA depends on whether the first value of seqB is 1 or not... Luckily, because seqA grows much faster than seqB, we only have to prime the pump a little.
seqA, seqB :: [Integer]
seqA = 1 : 3 : 7 : zipWith (+) (drop 2 seqA) (drop 2 seqB)
seqB = complement seqA
-- OR
seqA = 1 : zipWith (+) seqA seqB
seqB = 2 : 4 : drop 2 (complement seqA)
Try it in ghci:
> take 10 seqA
[1,3,7,12,18,26,35,45,56,69]
The definition of seqX is a bit less natural, but the definition of complement is a bit more natural, so there seems to be something of a tradeoff there.
As an answer to this part:
When I redefine the function in ghci, does it still use the older version for functions that call it previous to its redefinition?
Yes, that's the way it has to work. Bindings at the ghci prompt are not mutable variables as you would have in an imperative language, they're supposed to work the same way as variables do in every other part of Haskell.
So when you have this:
ghci> a = 1
ghci> b = [a]
ghci> b
[1]
a is just a name for 1, and b is just a name for [1]. The latter was calculated by from the expression [a] by seeing what value a was a name for, but it is absolutely the value [1] and not the expression [a] that b refers to.
ghci> a = 2
ghci> b
[1]
Executing a = 2 doesn't change the value referred to by a, it just changes the state of the environment available at the ghci prompt. This cannot affect any values that were calculated when a was a name for 1; they were and remain pure values.
An easy way to think about it is that a = 2 is not "changing a", it's just introducing a new and separate binding. Because it happens to have the same name as an existing one the new one shadows the old one, making the old one impossible for you to refer to in any future expressions. But nothing about the old one has been changed.
And you will in fact see exactly the same behaviour in a compiled module in contexts where you can have multiple bindings for one name (if you shadow a function argument with a let, or nest lets, etc). All but one of them will be inaccessible, but things that were defined in terms of the shadowed binding remain exactly the same; they aren't re-evaluated as if they were defined in terms of the new binding.
So with that in mind, it becomes easy to explain why this works:
ghci> seqB = [2, 4, 5, 6]
ghci> seqA = 1 : zipWith (+) seqA seqB
ghci> seqB = 2 : filter (`notElem` seqA) [3..]
ghci> seqA = 1 : zipWith (+) seqA seqB
ghci> hof = (!!) seqA
It's much the same as if you had defined it this way:
ghci> seqB_old = [2, 4, 5, 6]
ghci> seqA_old = 1 : zipWith (+) seqA_old seqB_old
ghci> seqB_new = 2 : filter (`notElem` seqA_old) [3..]
ghci> seqA_new = 1 : zipWith (+) seqA_new seqB_new
ghci> hof = (!!) seqA_new
seqB_old is just a finte list
Because zipWith stops at the length of the shortest list, seqA_old is also just a finite list, even though it's defined in terms of itself.
seqB_new is an infinite list that just has to filter each element against any of the elements of the finite list seqA_old; this doesn't get caught up in the problem amalloy points out, but it isn't actually the correct list you were trying to define
seqA_new is defined in terms of itself, but seqB_new was defined in terms of seqA_old, not this new version. There is simply no mutual recursion happening.
This problem doesn’t really lend itself to a mutually recursive solution. filter + notElem will continue searching beyond where they could ever return a result, because they can’t make any use of the fact that the sequence is strictly ascending.
Rather than searching for the next element that we haven’t seen, we can turn the problem around: start by assuming we will see every number, and use delete to prune out those numbers that we know we will want to exclude.
hof :: Int -> Int
hof = (!!) seqA
where
-- By definition, one is the cumulative sum of the other.
seqA = scanl' (+) 1 seqB
-- Iteratively build the sequence.
seqB = unfoldr (infinitely step) (1, [2 ..])
step c (d, xs) = (c, (c + d, delete (c + d) xs))
-- Helper for when ‘unfoldr’ is known to have
-- unbounded input (‘x : xs’ always matches)
-- and unbounded output (we always return ‘Just’).
infinitely f (d, x : xs) = Just (f x (d, xs))
Related
How might I go about efficiently generating an infinite list of Catalan numbers? What I have now works reasonably quickly, but it seems to me that there should be a better way.
c 1 = 1
c n = sum (zipWith (*) xs (reverse xs)) : xs
where xs = c (n-1)
catalan = map (head . c) [1..]
I made an attempt at using fix instead, but the lambda isn't lazy enough for the computation to terminate:
catalan = fix (\xs -> xs ++ [zipWith (*) xs (reverse xs)])
I realize (++) isn't ideal
Does such a better way exist? Can that function be made sufficiently lazy? There's an explicit formula for the nth, I know, but I'd rather avoid it.
The Catalan numbers [wiki] can be defined inductively with:
C0 = 1 and Cn+1=(4n+2)×Cn/(n+2).
So we can implement this as:
catalan :: Integral i => [i]
catalan = xs
where xs = 1 : zipWith f [0..] xs
f n cn = div ((4*n+2) * cn) (n+2)
For example:
Prelude> take 10 catalan
[1,1,2,5,14,42,132,429,1430,4862]
I'm guessing you're looking for a lazy, infinite, self-referential list of all the Catalan numbers using one of the basic recurrence relations. That's a common thing to do with the Fibonacci numbers after all. But it would help to specify the recurrence relation you mean, if you want answers to your specific question. I'm guessing this is the one you mean:
cat :: Integer -> Integer
cat 1 = 1
cat n = sum [ cat i * cat (n - i) | i <- [1 .. n - 1] ]
If so, the conversion to a self-referential form looks like this:
import Data.List (inits)
cats :: [Integer]
cats = 1 : [ sum (zipWith (*) pre (reverse pre)) | pre <- tail (inits cats) ]
This is quite a lot more complex than the fibonacci examples, because the recurrence refers to all previous entries in the list, not just a fixed small number of the most recent. Using inits from Data.List is the easiest way to get the prefix at each position. I used tail there because its first result is the empty list, and that's not helpful here. The rest is a straight-forward rewrite of the recurrence relation that I don't have much to say about. Except...
It's going to perform pretty badly. I mean, it's better than the exponential recursive calls of my cat function, but there's a lot of list manipulation going on that's allocating and then throwing away a lot of memory cells. That recurrence relation is not a very good fit for the recursive structure of the list data type. You can explore a lot of ways to make it more efficient, but they'll all be pretty bad in the end. For this particular case, going to a closed-form solution is the way to go if you want performance.
Apparently, what you wanted is
> cats = 1 : unfoldr (\ fx -> let x = sum $ zipWith (*) fx cats in Just (x, x:fx)) [1]
> take 10 cats
[1,1,2,5,14,42,132,429,1430,4862]
This avoids the repeated reversing of the prefixes (as in the linked answer), by unfolding with the state being a reversed prefix while consing onto the state as well as producing the next element.
The non-reversed prefix we don't have to maintain, as zipping the reversed prefix with the catalans list itself takes care of the catalans prefix's length.
You did say you wanted to avoid the direct formula.
The Catalan numbers are best understood by their generating function, which satisfies the relation
f(t) = 1 + t f(t)^2
This can be expressed in Haskell as
f :: [Int]
f = 1 : convolve f f
for a suitable definition of convolve. It is helpful to factor out convolve, for many other counting problems take this form. For example, a generalized Catalan number enumerates ternary trees, and its generating function satisfies the relation
g(t) = 1 + t g(t)^3
which can be expressed in Haskell as
g :: [Int]
g = 1 : convolve g (convolve g g)
convolve can be written using Haskell primitives as
convolve :: [Int] -> [Int] -> [Int]
convolve xs = map (sum . zipWith (*) xs) . tail . scanl (flip (:)) []
For these two examples and many other special cases, there are formulas that are quicker to evaluate. convolve is however more general, and cognitively more efficient. In a typical scenario, one has understood a counting problem in terms of a polynomial relation on its generating function, and now wants to compute some numbers in order to look them up in The On-Line Encyclopedia of Integer Sequences. One wants to get in and out, indifferent to complexity. What language will be least fuss?
If one has seen the iconic Haskell definition for the Fibonacci numbers
fibs :: [Int]
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
then one imagines there must be a similar idiom for products of generating functions. That search is what brought me here.
I am a bit surprised that this was not asked before. Maybe it is a stupid question.
I know that flip is changing the order of two arguments.
Example:
(-) 5 3
= 5 - 3
= 2
flip (-) 5 3
= 3 - 5
= -2
But why would I need such a function? Why not just change the inputs manually?
Why not just write:
(-) 3 5
= 3 - 5
= -2
One is unlikely to ever use the flip function on a function that is immediately applied to two or more arguments, but flip can be useful in two situations:
If the function is passed higher-order to a different function, one cannot simply reverse the arguments at the call site, since the call site is in another function! For example, these two expressions produce very different results:
ghci> foldl (-) 0 [1, 2, 3, 4]
-10
ghci> foldl (flip (-)) 0 [1, 2, 3, 4]
2
In this case, we cannot swap the arguments of (-) because we do not apply (-) directly; foldl applies it for us. So we can use flip (-) instead of writing out the whole lambda \x y -> y - x.
Additionally, it can be useful to use flip to partially apply a function to its second argument. For example, we could use flip to write a function that builds an infinite list using a builder function that is provided the element’s index in the list:
buildList :: (Integer -> a) -> [a]
buildList = flip map [0..]
ghci> take 10 (buildList (\x -> x * x))
[0,1,4,9,16,25,36,49,64,81]
Perhaps more frequently, this is used when we want to partially apply the second argument of a function that will be used higher-order, like in the first example:
ghci> map (flip map [1, 2, 3]) [(+ 1), (* 2)]
[[2,3,4],[2,4,6]]
Sometimes, instead of using flip in a case like this, people will use infix syntax instead, since operator sections have the unique property that they can supply the first or second argument to a function. Therefore, writing (`f` x) is equivalent to writing flip f x. Personally, I think writing flip directly is usually easier to read, but that’s a matter of taste.
One very useful example of flip usage is sorting in descending order. You can see how it works in ghci:
ghci> import Data.List
ghci> :t sortBy
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
ghci> :t compare
compare :: Ord a => a -> a -> Ordering
ghci> sortBy compare [2,1,3]
[1,2,3]
ghci> sortBy (flip compare) [2,1,3]
[3,2,1]
Sometimes you'll want to use a function by supplying the second parameter but take it's first parameter from somewhere else. For example:
map (flip (-) 5) [1..5]
Though this can also be written as:
map (\x -> x - 5) [1..5]
Another use case is when the second argument is long:
flip (-) 5 $
if odd x
then x + 1
else x
But you can always use a let expression to name the first parameter computation and then not use flip.
I've looked at different folds and folding in general as well as a few others and they explain it fairly well.
I'm still having trouble on how it would work in this case.
length :: [t] -> Int
length list = foldr (+) 0 (map (\x ->1) list)
Could someone go through that step by step and try to explain that to me.
And also how would foldl work as well.
(map (\x ->1) list) takes the list and turns it into a list of 1 values:
(map (\x ->1) ["a", "b", "c"]) == [1, 1, 1]
Now, if you substitute that in the original foldr, it looks like this:
foldr (+) 0 [1, 1, 1]
The starting point is 0 and the aggregation function is (+). As it steps through each element in the list, you are basically adding up all the 1 values, and that's how you end up returning the length.
foldr starts from the right and works back to the head of the list. foldl starts from the left and works through the list. Because the aggregation function is (+) :: Num a => a -> a -> a, the ordering of the left and right arguments in (+) is logically inconsequential (with the caveat that foldl has stack overflow problems with large lists because of lazy evaluation)
Trying to create a Haskell program that increments every number in a list by one.
module Add1List where
add1_list_comp :: [Integer] -> [Integer]
add1_list_comp [x] = [x + 1| x <- [x]]
It works when I call this add1_list_comp [3] ... it gives me [4]
But when I do add1_list_comp [3, 4, 5] ... it throws me an error saying
"non-exhaustive patterns in function add1_list_comp"
Any help would be much appreciated!
add1_list_comp = map succ
that simple
or, in your way
add1_list_comp xs = [x + 1| x <- xs]
the problem with your code is that
add1_list_comp [x]
does pattern match on list with single item, that's why it fails on list with several items.
I see that the question has been answered, but perhaps I can explain a bit more.
The argument of a function is pattern matched, and the general rules are
(x:xs)
x is the head of the list and xs is the tail of the list, and potentially empty list
[]
empty list
[x] or (x:[])
are the same which is a list with only one variable
and a name with no constructor such as "[]", ":", "(,)" around can match anything, so if you want to match a special case, you should put the special case in front of the general pattern.
length [] = 0
length [x] = 1
length (x : xs) = 1 + length xs
BTW, generally speaking, there will always be a higher order function when you want to do something with a list. for your case
add1 xs = map (+1) xs
is nicer and it took advantage of the built in library, and you can also do a point free version of it
add1 = map (+1)
Well actually since the topic states "Increment by One" without defining what type is going to be incremented by one, just for the sake of a visitor ended up here lets give a solution which would increment any functor by one, which of course includes the list type. So;
List functor
*Main> fmap (+1) [1,2,3]
[2,3,4]
Maybe functor (id applies to Nothing)
*Main> fmap (+1) (Just 1)
Just 2
Either functor (id applies to Left _)
*Main> fmap (+1) (Right 2)
Right 3
IO functor
*Main> fmap ((+1) . read) getLine
2017
2018
I've been trying to do the 2nd Project Euler problem in haskell but I've been getting: Occurs check: cannot construct the infinite type: a = [a]
fibonacci 0 _ = 0
fibonacci 1 _ = 1
fibonacci x xs = (xs!!(x-2)) + (xs!!(x-1))
fibonaccisLessThan = takeWhile(<40) $ foldr fibonacci [] [0..]
sumOfEvenFibonaccis = sum $ filter even $ fibonaccisLessThan
main = putStrLn $ show $ sumOfEvenFibonaccis
Can someone tell me why?
Think about lines one to five. What do you want to achieve? You want to get a lazy list of Fibonaccis. But your approach is very strange. I don't see through your code, but I think I have an idea about what you try to do. Try to give your functions type-signatures, then you will see quickly, what's going wrong.
Here is a shorter way:
Think of short cutting your approach. Let's try to define a lazy list of Fibonacci numbers:
fibs = undefined
So, what now? The first thing we know, is that the first two elements are 0 and 1:
fibs = 0 : 1 : undefined
And the rest? It is fibs added with a shifted version of fibs. Look at this. zipWith f combines a list with another list using a function f:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
And here we are. That's all.
The reason for your error message is that the function fibonacci returns a number, nevertheless, you use it at line 5 as if it would return a list of that same kind of number.
This causes the type checker to try to unify a type "a" with the type "[a]" and this gives the occurs check error.
Think about it: where in your program is the list actually constructed? You know, there should be a : operator applied somewhere, directly or indirectly, but it isn't. Therefore, in your program, the list of fibonacci numbers is entirely fictional.
Some general advice: If you get a strange type error, make sure you have type signatures on all top level definitions. This ensures that your type error will be reported in the right definition.
That said, your fibonacci definition is weird.
Let us start by first noticing that fibonacci has type Int -> [Int] -> Int, and that foldr has type (a -> b -> b) -> b -> [a] -> b, so we can't give fibonacci to foldr since we can't unify a-> b-> b with Int -> [Int] -> Int. This is where the error message comes from.
To fix it we have to change the fibonacci function. fibonacci = 0 : 1 : zipWith (+) fibonacci (tail fibonacci) is the classic haskell way of doing it, for more ways take a look at this haskellwiki page. Then all you have to do is:
sumOfEvenLessThen n = sum . filter even . takeWhile (<n)
main = print $ sumOfEvenLessThen 40 fibonacci
The other answers already point out where the error comes from, and show the very compact and elegant "standard" definition of Fibonacci numbers in Haskell. Here is another way to define it, which might be more beginner friendly:
fibs = map fst $ iterate next (0,1) where
next (x,y) = (y,x+y)
The idea is to keep track not only of the last, but of the last two Fibonacci numbers, which can be done using pairs. With this trick it's very easy to define the recursive relationship.
We start with the argument (0,1) and generate a list from this start value using the next function over ond over again: [(0,1),(1,1),(1,2),(2,3),(3,5)...]. Then the only thing left to do is to "throw away" the second argument of the pairs, which is done by map fst $ ....
[Update]
Another nice definition (working similar like the zipWith-Version) is:
fibs = 0 : scanl (+) 1 fibs