0
votes

I have a simple haskell program that returns the index of a specific number (say variable "i" from "mylist", and should return the index like.. "(Ind i)". "Num" is of type Int. nums is declared as a list.

This may be easy for some, but could you help me, what is wrong with my simple code? It says "parse error on input `)'".

list1 :: Int -> Int
list1 (Num i) = (do let j = [nums] !! i; return (Ind j));
....

I'm a newbie in haskell. :( help!

4
If you're new to Haskell, best stay away from the do construct and monads in general. Get used to the pure functional style first. - Thomas
Your problem description is unclear. Can you show us some input/expected output examples? - chi
Say I have a list called nums = [30, 20, 10, 40].. my code should return the position/index number in the list. If i=20, then the result should return "Ind 2", because number 20 is 2nd in the list. @chi - Sushi
Did you declare Num and Ind yourself? Please show those datatypes/constructors - Bergi

4 Answers

1
votes

You probably want something like this:

find :: Eq a => a -> [a] -> Int
find i [] = -1    -- not found
find i (x:xs) = if i==x then 0 else 1 + find i xs

The above is not the most elegant solution, but uses only basic notions.

Another variant could be

find :: Eq a => a -> [a] -> Int
find i list = go 0 list
    where go _ []     = -1     -- not found
          go n (x:xs) = if i==x then n else go (n+1) xs

You should return Nothing instead of -1, though, even if this requires changing the return type from Int to Maybe Int. This is also done by the elemIndex library function, which solves this task.

0
votes

If you want to use the single-line do notation, it needs to look like do {x; y; z} - parentheses do not suffice for delimiting it. But also this doesn't look like it needs do at all - in fact I can't figure out at all what your function is supposed to do, so I can't fix it for you. What is the intended purpose of this function?

0
votes

There is no need for do notation, since this should be a pure function. What is nums? Should it perhaps be an argument to list1? Is Ind a constructor, or are you trying to return a string that reads "Ind "++ show j? Last, using !! is not appropriate here - it will look up the ith item in the list, while I think you want to find an item equal to i in the list.

I would suggest solving this with manual recursion for practice, then looking at Data.List for a more idiomatic solution. Here's a simple recursive version:

list1 :: Eq a => [a] -> a -> Maybe Int
list1 ls item = helper ls item 0
  where helper :: Eq a => [a] -> a -> Int -> Maybe Int
        helper [] _ _ = Nothing
        helper (x:xs) m n
          | x == m = Just n
          | otherwise = helper xs m (n+1)
0
votes

This is how I would approach the problem: limit the do notation to the final call, in this case in the main function. The rest is pure.

nums = [1,2,3]

list1 aList aNumber = list2 aList aNumber 0

list2:: [Int] -> Int -> Int -> Int
list2 [] aNumber aCount = 0
list2 (h:xs) aNumber aCount = if h == aNumber then aCount + 1
                        else list2 xs aNumber (aCount + 1)


main = do
  let index = list1 [1,2,3]  3
  putStrLn $ show index

Will this work for you?