简体   繁体   中英

Haskell's code indentation issue in function's definition

I was trying to code mergesort in Haskell, but something goes wrong. I think the following code should be correct

-- UPDATE : COMPLETE PROGRAMM'S CODE
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) 
    | x <= y = x:merge xs (y:ys)
    | otherwise = y:merge (x:xs) ys

mergeSort xs
    | length xs < 2 = xs
    | otherwise  = merge (mergeSort (myleft xs)) (mergeSort (myright xs))
       where myleft xs = take (half xs) xs
             myright xs = drop (half xs) xs
             where half = \xs -> div (length xs) 2 

Since first where is referred to "otherwise" line it's indented farther than that. The second where is referred to all the first "where block", so it should be nested in the first one. When compiling it gives me this error

 Variable not in scope: mergeSort
   |
26 |  mergeSort xs
   |  ^^^^^^^^^

So there's something wrong with the function's definition. I tried to fix the layout in many different ways, for example

 mergeSort xs
    | length xs < 2 = xs
    | otherwise  = merge (mergeSort (myleft xs)) (mergeSort (myright xs))
    where myleft xs = take (half xs) xs
          myright xs = drop (half xs) xs
          where half = \xs -> div (length xs) 2 

But none of them works.

I also looked for solution here and I found something which is pretty close to what I was doing --> Haskell Merge Sort It also provides a correct code

mergeSort merge xs
        | length xs < 2 = xs
        | otherwise = merge (mergeSort merge first) (mergeSort merge second)
        where first = take half xs 
              second = drop half xs 
              half = length xs `div` 2

But why does this work? Isn't it needed a second where to specify "half"? Why is it absent? Can't understand why mine isn't working anyway.

In your code half is only "visible" in the myright definition.

Removing the second where works:

merge :: [a] -> [a] -> [a]
merge = undefined

mergeSort :: [a] -> [a]
mergeSort xs
  | length xs < 2 = xs
  | otherwise  = merge (mergeSort (myleft xs)) (mergeSort (myright xs))
     where myleft xs = take (half xs) xs
           myright xs = drop (half xs) xs
           half = \xs -> div (length xs) 2 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM