0

This portion of code checks if a number given (First element in a list) is zero (yes i tried == 0 but got other errors) It then return all elements of another list except the first one. If not, it returns another list. The function is of type [a] and 'newpack' needs to be a variable as it is used later.

                              if ((position!!1) < 1)
                                then 
                                    let newpack =   drop ((length pack)-1) pack
                                else
                                    let newpack = (take ((position!!1)-1) pack) ++ (drop ((position!!1)+1) pack)

error is 46:73: parse error on input `else'

Do have any idea why this is not working? Is it that'let's needs an 'in' with them?

Thanks for your help,

J

2
  • Note: position !! 1 yields the second element of the list position (or a runtime error, if it is too short). Indices are 0-based. Commented Mar 23, 2012 at 19:15
  • If you come from a C-style language, just train yourself to exchange every Haskell if a then b else c with a? b : c in your mind. What imperative languages call if is when in Haskell (not available by default, you have to import Control.Monad), but you can't use that in this way either. Commented Mar 23, 2012 at 19:38

2 Answers 2

4

Yes, the in part is not optional. You can write this as:

let newpack = if (position !! 1) < 1
                then drop ((length pack)-1) pack
                else (take ((position!!1)-1) pack) ++ (drop ((position!!1)+1) pack)
in ...rest of code...

If you're in a do block, then you can omit in onwards, but either way, you can't put the conditional outside the binding.

(If you're hoping to modify newpack as if it was a mutable variable, that's just not possible; all let does is give a name to a value, you can't actually modify anything. But how to structure your code without this would be beyond the scope of this question; if you need help with that, you should ask another.)

Some stylistic notes:

  • Explicit list indexing is generally considered a bad idea; depending on what it's used for, you might want to consider making position a tuple or some other data structure.

  • Similarly, length is probably a bad idea too (it has to traverse the entire list just to give a result).

  • You have a lot of redundant parentheses: drop ((length pack)-1) can be simply drop (length pack - 1).

A nicer way to write this (from a purely aesthetic point of view — i.e. ignoring the list indexing and use of length) would be (using guards):

let firstPos = position !! 1
    newPack
      | firstPos == 0 = drop (length pack - 1) pack
      | otherwise     = take (firstPos - 1) pack ++ drop (firstPos + 1) pack
in ...
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for this, it seems like an intelligent solution and bonus for stylistic notes. I seem to have problems with guards (I am using Kate program on Linux OS) giving me a 45:65: parse error on input `|'
You might be indenting your code with tabs. Make sure there are only spaces in your file, no tabs; if there are tabs, look up how to set your editor to expand them to spaces. (Basically, Haskell interprets tabs as 8 spaces, which means that if your editor shows them as smaller than that, things can look lined up to your editor but totally wrong to Haskell.)
I enabled this feature on Kate, fiddled with the code and it works exactly how i want it to now. @daniel-fischer this was also a useful piece of information that i overlooked (the position!!0). Cheers guys.
2

Is it that 'let's needs an 'in' with them?

Yes. (do-blocks are a special case; however, even in a do-block, the rest of the block is a bit like being in an implicit in.) You might consider writing something like this:

let newpack = if {- ... -} then {- ... -} else {- ... -} in
{- the rest of your computation that uses newpack -}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.