views:

381

answers:

9

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:

C:\Users\Martin\Desktop\Haskell\Q1.hs:7:33:
    parse error (possibly incorrect indentation)

I don't understand what I'm doing wrong.

Edit:: Now I now, gotta call things inside a main function. However having fixed that to look 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 this:

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 to solve!

+2  A: 

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
sth
+6  A: 

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.

Yacoby
That's a good point, changed now, thanks :)
Martin
+2  A: 

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.

mipadi
+1 for poiting out more clearly what caused the error, not just the correction
Thiago Arrais
+3  A: 

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:

  1. You need to import Data.List in order to use group.
  2. No need to use foldr in this case: by using map the length of each group is only calculated once.
  3. This does mean, of course, that we call in the help of another function, maximum.
Stephan202
Ok, so that's a better solution. I would still like to understand this new error I'm getting though
Martin
+5  A: 
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]
Caleb
This works. But I'm unfamiliar with the $ operator
Martin
"llfs li = length $ foldl1 longest $ group li" Is the same as "llfs li = length (foldl1 longest ( group li))
Yacoby
@Martin: then find a good tutorial and get familiar with the $ operator. It's very, very useful ;-) @Caleb: you don't need 'do' for only one statement.
Nefrubyr
Well using foldl1 instead of foldl fixed the problem!
Martin
Damn, I understand why, I misread the documentation for foldl and foldl1
Martin
+5  A: 

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.)

Nefrubyr
+2  A: 

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.

Chuck
I know it's pointless, I just find it easier to read...
Martin
@Martin: It will be harder for most Haskell programmers. I think you're just not used to Haskell syntax yet.
Chuck
I'm not, I've been learning haskell for all of eleven hours.
Martin
+1  A: 

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.

Dan
+1  A: 
module Longest where
import Data.List

-- Returs the length of the longest list from a given list of lists
longestGroup :: [[a]] -> Int
longestGroup = maximum . (map length)

main = do
   print $ longestGroup $ group [1,2,3,3,4,5,1,1,1]

-- same as
-- print (longestGroup (group [1,2,3,3,4,5,1,1,1]) )
Matt von Rohr