I have a Haskell file which looks like this:
longest::[Integer]->[Integer]->[Integer]
max a b = if length a > length b then a else b
llfs::[Integer]->Integer
llfs li = length(foldl longest group(li))
llfs([1, 2, 3, 3, 4, 5, 1, 1, 1])
Which should print out the result of the function call at the end, however when I run the file I get this error:
parse error (possibly incorrect indentation)
I don't understand what I'm doing wrong. What should I do to fix it?
Edit
After putting the last line inside the main function, like this:
import List
longest::[Integer]->[Integer]->[Integer]
longest a b = if length a > length b then a else b
llfs::[Integer]->Integer
llfs li = length(foldl longest group(li))
main = print (llfs [1, 2, 3, 3, 4, 5, 1, 1, 1])
I now get the following error:
C:\Users\Martin\Desktop\Haskell\Q1.hs:7:31:
Couldn't match expected type `[Integer]'
against inferred type `[a] -> [[a]]'
In the second argument of `foldl', namely `group'
In the first argument of `length', namely
`(foldl longest group (li))'
In the expression: length (foldl longest group (li))
This one looks a little more difficult! How do I solve it?
Your code isn't correct.
This
longest::[Integer]->[Integer]->[Integer]
max a b = if length a > length b then a else b
should be
longest::[Integer]->[Integer]->[Integer]
longest a b = if length a > length b then a else b
And you need a main function
main = do print llfs([1, 2, 3, 3, 4, 5, 1, 1, 1])
Just for the sake of improving your code, if you have a function signature and give it a lower case letter(s) as its type (say the letter a), it becomes generic. For example
longest:: [a] -> [a] -> [a]
longest x y = if length x > length y then x else y
Means that rather than just working on lists of Integers, it works on lists of anything. Suddenly you have a very reusable function.
In the line
llfs li = length(foldl longest group(li))
the interpreter is treating group as the second argument to foldl. Writing group(li) is no different from writing group li.
Also, foldl needs an initial value. foldl1, on the other hand, uses the first list element for its initial value. Try:
llfs li = length (foldl1 longest (group li))
(Edited to remove the first, wrong answer.)
module Main where
import Data.List
longest::[Integer]->[Integer]->[Integer]
longest a b = if length a > length b then a else b
llfs::[Integer]->Int
llfs li = length $ foldl1 longest $ group li
main = do
putStrLn $ show $ llfs [1, 2, 3, 3, 4, 5, 1, 1, 1]
The problem was that the last line did not define a function, as others have stated. More things are wrong in your code. It appears this is what you want to do:
import Data.List
longest_group_size :: [Integer] -> Int
longest_group_size = maximum . map length . group
main :: IO ()
main = print $ longest_group_size [1, 2, 3, 3, 4, 5, 1, 1, 1]
Observe that:
You need to import Data.List in order to use group.
No need to use foldr in this case: by using map the length of each group is only calculated once.
This does mean, of course, that we call in the help of another function, maximum.
You cannot call a function at file scope like you would do in python or other scripting languages. Therefore the "call" to llfs in the last line is an error. Try printing the result in main:
main = print (llfs [1, 2, 3, 3, 4, 5, 1, 1, 1])
At the moment the "function call" looks like an incomplete function definition, where the right side is missing, which leads to the surprising error message:
llfs (...) = abc
The problem is this line:
llfs([1, 2, 3, 3, 4, 5, 1, 1, 1])
That's not a function declaration. I think you're trying to make a function call, in which case you need to put it inside a main declaration. You can also load the Haskell file into an interpreter (e.g., ghci) and execute the function call in the interpreter console.
This isn't the direct cause of either error, but I think it's a contributing factor to your misunderstanding. In Haskell, you would never write group(li). Parenthesizing a single argument is pointless — it's exactly equivalent to group li. If you're trying to pass the result of this function call to another function, you need to parenthesize the whole expression — (group li) — or use the $ operator like Caleb suggested.
Two small issues with the update. First, it looks like you're trying to pass the group result as an argument to foldl. The right way to say that is (group li) rather than group(li) The second is that foldl needs a base case. Caleb's suggestion to use foldl1 is one option that will probably work for you.
Related
I'm writing a simple interpreter that people can use (among other things) to sort a list via a comparison function (preferably a stable sort). Sorting algorithms that I'm familiar with all seem to require a variable number of calls to that comparison function and you don't know ahead of time which items will be compared to each other. That won't work because of the nature of what work is done in the interpreted language vs the runtime at what times.
The steps required by the interpreter are:
Step 1: Create a list of as to be compared to another list of bs, one a & b at a time. Something like sort([1, 2, 3]) producing:
a = [2, 3]
b = [1, 2]
(2 is compared to 1 and then 3 is compared to 2 in the above example, going index by index.)
Step 2: Create two new lists (before and after) with the same number of items as a and b to represent the result of the comparison function. The values are any null or non-null value. Something like:
before = [2, 3]
after = [null, null]
(2 should come before 1, representing 1 from b as null. The non-null values are preserved, but any non-null value could be in 2's place.)
I can impose a limitation that the values in before and after must be items from the lists a and b, but I'd prefer not to if I possibly can. I mention it because I'm unsure how I could know where the non-null value came from (a or b). But if the items compared from a and b are the same but only one is null at the end, I have the same problem.
Step 3: Use those two lists before and after to sort the original list. Something like:
sort([1, 2, 3], greaterThan) => [3, 2, 1]
// a = [2, 3]
// b = [1, 2]
// before = [2, 3]
// after = [null, null]
(If both values are non-null or both null, it should favor their original order relative to each other, or a "stable" sort.)
In such a trivial example, the items in a and b are sufficient to sort the list. The Javascript (the language the interpreter is written in) Array.sort method will compare them like this:
(2, 1)
(3, 2)
and be done. But if the order of the original list were [2, 3, 1] then it has to do:
(3, 2)
(1, 3)
(1, 2)
(1, 3)
(I don't know why or what algorithm they use).
In that example, I would have to provide lists a and b as [3, 1, 1, 1] and [2, 3, 2, 3] respectively.
How do I get a list for a and b that will work given any comparison function or order of the original list -- and then use the resulting before and after lists to sort that original list?
The Lucas Sequence is a sequence of numbers. The first number of the sequence is 2. The second number of the Lucas Sequence is 1. To generate the next number of the sequence, we add up the previous two numbers. For example, the first six numbers of the sequence are: 2, 1, 3, 4, 7, 11, ...
Write a method lucasSequence that accepts a number representing a length as an arg. The method should return an array containing the Lucas Sequence up to the given length. Solve this recursively.
def lucas_sequence(length)
return [] if length == 0
return [2] if length == 1
return [2, 1] if length == 2
seq = lucas_sequence(length - 1)
next_el = seq[-1] + seq[-2]
seq << next_el
seq
end
p lucas_sequence(0) # => []
p lucas_sequence(1) # => [2]
p lucas_sequence(2) # => [2, 1]
p lucas_sequence(3) # => [2, 1, 3]
p lucas_sequence(6) # => [2, 1, 3, 4, 7, 11]
p lucas_sequence(8) # => [2, 1, 3, 4, 7, 11, 18, 29]
**I'm having a hard time understanding the recursion logic behind this. Can someone explain how the computer is solving this?
Does the computer read the length and then add up from [2,1] until it reaches its length? If so, how does it continuously count down? **
Recursion is the programming equivalent of mathematical induction. Given a series, assume that the problem is solved for the previous member of the series and provide the rule for generating this member.
So, consider just these lines:
def lucas_sequence(length)
seq = lucas_sequence(length - 1) # <1>
next_el = seq[-1] + seq[-2] # <2>
seq << next_el # <3>
seq # <4>
end
That says:
You want to know the lucas sequence of a certain length (length). Fine, first tell me the previous lucas sequence, the sequence that is one unit shorter than this (length-1). (That is the recursion: the lucas_sequence method, itself, calls the lucas_sequence method, but with a reduced length value.)
Add up the last two members of that shorter sequence...
...and append the sum to that shorter sequence...
...and the result is this sequence, the one you asked for.
And that's basically all there is to it! The only problem is that there is no place to start. We assume that for the seq of length 4, we have solved 3 already, which we get by assuming that we have solved 2 already, which we get by assuming we have solve 1 already... But we haven't actually solved any of those!
So we begin by backstopping the most degenerate cases:
return [] if length == 0
return [2] if length == 1
return [2, 1] if length == 2
Now the problem is solved if length is 0, 1, or 2, because we just give those answers directly. Okay, so if length is 3, we solve with reference to 2, which is known. Okay, if length is 4, we solve with reference to 3, and I just told you how to do that. Okay, if length is 5, we solve with reference to 4, and I just told you how to do that. And so on, for any length you care to give me.
So it is essentially a modified Fibonacci sequence. Best way to solve most structured sequences is with an Enumerator e.g.
lucas = Enumerator.new do |y|
a,b = 2,1
loop do
y << a
a, b = b, a + b
end
end
Then
lucas.first(10)
#=> [2, 1, 3, 4, 7, 11, 18, 29, 47, 76]
First we create a new Enumerator and then assign a and b to your starting values (2 and 1 respectively).
To generate the sequence we use a loop which will lazily yield the values to the yielder (y).
Here we push in a then we assign a to bs value and bs value to a + b in parallel to avoid overwriting a before the addition of a + b.
I'm having trouble understanding these two sections in ruby-doc:
Implicit Array Assignment
Multiple Assignment
When it says left-hand side, the splat operator is on the right side, and when it says right-hand side, the operator is on the left side. For example:
The * can appear anywhere on the right-hand side:
*a, b = 1, 2, 3
p a: a, b: b # prints {:a=>[1, 2], :b=>3}
Can anyone explain me what the meaning of left-hand side and right-hand side is in these sections? To me, examples seem contradictory.
I think this is a mistake in this v2.0.0 reference manual. Your understanding is correct.
Both have been fixed in the v2.2.0 manual (Implicit Array Assignment and Multiple Assignment).
I think it is supposed to mean what you have in mind. However, the document looks like it has mistakes. You can report this to the developers here as a documentation bug.
* will turn an argument list in to an array and visa versa:
def do_it(*args)
args
end
do_it(1, 'hello') # => [1, 'hello']
In the case of *a, b = 1, 2, 3 it is processed right to left, b is assigned 3 and the remaining arguments, 2 and 3 to a as an array, [2, 3].
In the case of a = 1, *[2,3], the array, [2, 3], is converted to arguments 2, 3. Therefore equivalent to a = 1, 2, 3.
Why a = 1, 2, 3 is valid and does not cause an error I do not know. I would guess, Ruby does an implicit splat when you supply multiple arguments to a single var assignment. So a = [1, 2, 3] is functionaly the same as a = 1, 2, 3.
This works in Ruby:
a = 4..Float::INFINITY
p a.take(4) #=> [4,5,6,7]
But I was wondering if it's possible to do something similar where the range would be from negative infinity up to a certain number, say 4, and have a method that will take the last, say 6 elements from that sequence, which would be [-1,0,1,2,3,4].
Getting the last N numbers from a range -infinity..4 is the same of selecting a range of 4..(4-N).
4.downto(4-5).to_a
# => [4, 3, 2, 1, 0, -1]
You can package it as a custom method
def lastn(from, n)
from.downto(from-n).to_a
end
How about the last method?
a.last(6)
Run the following code,
a = [1, 2, 3, 4, 5]
head, *tail = a
p head
p tail
You will get the result
1
[2, 3, 4, 5]
Who can help me to explain the statement head,*tail = a, Thanks!
head, *tail = a means to assign the first element of the array a to head, and assign the rest of the elements to tail.
*, sometimes called the "splat operator," does a number of things with arrays. When it's on the left side of an assignment operator (=), as in your example, it just means "take everything left over."
If you omitted the splat in that code, it would do this instead:
head, tail = [1, 2, 3, 4, 5]
p head # => 1
p tail # => 2
But when you add the splat to tail it means "Everything that didn't get assigned to the previous variables (head), assign to tail."
First, it is a parallel assignment. In ruby you can write
a,b = 1,2
and a will be 1 and b will be 2. You can also use
a,b = b,a
to swap values (without the typical temp-variable needed in other languages).
The star * is the pack/unpack operator. Writing
a,b = [1,2,3]
would assign 1 to a and 2 to b. By using the star, the values 2,3 are packed into an array and assigned to b:
a,*b = [1,2,3]
I don't know Ruby at all, but my guess is that the statement is splitting the list a into a head (first element) and the rest (another list), assigning the new values to the variables head and tail.
This mechanism is usually referred (at least in Erlang) as pattern matching.