tags:

views:

139

answers:

3

I'm trying to run this code:

let coins = [50, 25, 10, 5, 2,1]

let candidate = 11

calculate :: [Int]
calculate = [ calculate (x+candidate) | x <- coins, x > candidate]

I've read some tutorials, and it worked out ok. I'm trying to solve some small problems to give-me a feel of the language. But I'm stuck at this.

test.hs:3:0: parse error (possibly incorrect indentation)

Can anyone tell me why? I've started with haskell today so please go easy on the explanations.

I've tried to run it like:

runghc test.hs
ghc test.hs

but with:

ghci < test.hs

it gives this one:

<interactive>:1:10: parse error on input `='

Thanks

+3  A: 

I'm also pretty new to haskell, but this is what I have gathered so far

In ghci, you cannot define a function without let

In a .hs file, you cannot define a function with let

karoberts
+1  A: 

Using let is tricky. In a Haskell .hs file that you intend to compile with ghc or to run with runghc or runhaskell, you don't need to use let to define values and functions. So you should just do:

test = ...
candidate = ...
calculate = ...

In a do block, or when using the interpreter which actually runs your code as though it were written inside a do block, whenever you define values and functions, you should use the let keyword. So inside a do block or within a ghci session, you might do

let test = ...
let candidate = ...
let calculate = ...

As one final note, you might use the keyword let outside of a do block or ghci session when making a temporary value to be used within a larger definition, such as:

calculate =
    let test = ... in
    let candidate = ... in
    ... {stuff that uses test and candidate}
Justice
It's not so much that using `let` is tricky as just that the GHCi interpreter is tricky. If you ignore GHCi, `let` makes perfect sense.
Chuck
Some functional languages require all definitions to begin with `let` or `letrec`. Haskell makes things more concise, but includes the `let` keyword and even requires it in certain cases. I would say that for someone just starting out in functional programming with Haskell, given the `where` keyword, `let` would rarely come up outside `do` blocks because Haskell simply has you write `{name} = {definition}` throughout.
Justice
in your last code block, you could have used one `let/in`, also `test` would be in scope in `candidate` and vice versa, as well as both being available in the `in` section
jberryman
@jberryman, that is absolutely correct. Thank you for your suggestions. The only reason I didn't write it as you suggested is that I wanted to focus purely on `let` rather than on the code as a whole - I wanted to use `let` in the simplest, clearest ways I could, rather than write clear, idiomatic Haskell code.
Justice
+4  A: 

1) Top level declarations don't need 'let'. You probably want:

coins = [50, 25, 10, 5, 2,1]

candidate = 11

2) Calculate is explicitly typed as a list and used as a function.

Here is where you say calculate is a list of integers:

calculate :: [Int]

And inside the list comprehension you used calculate (x+candidate), but you already explicitly made calculate a list and not a function - so this can not work.

calculate = [ calculate (x+candidate) | x <- coins, x > candidate]

Perhaps you wanted something like:

newCoins = [ x + candidate | x <- coins, x > candidate]

It would help if you explained more of what you want as a result.

TomMD
please explain the 2), tks
fmsf
I'm following this: http://www.haskell.org/~pairwise/intro/section1.html and I saw some examples of stuff like that so i was trying it out
fmsf
@fmsf: The type you gave for calculate indicates that it is a (constant) list of Ints. But definition you gave for `calculate` appears to be a function (not a list) taking an `[Int]` argument `coins` and performing some kind of calculation on it. So type should be something like `calculate :: [Int] -> [Int]`. But the recursive call to `calculate (x + calculate)` still doesn't make much sense, as that would imply that `calculate` takes an Int rather than a list.
Chuck
I can't explain directly what i want to do that would be cheating, has I'm doing it as an alternative implementation for a univ assignement. but you helped a lot tks
fmsf