Search code examples
haskellparse-error

strange haskell parse error


So I've only a little experience with Haskell and I've been working on the below program to implement a search to find maxima in a function, yet I've been receiving an odd error. When I compile it says:

MaximaSearch.hs:26:1: parse error (possibly incorrect indentation or mismatched brackets)

That's the line that says "main = do" so I think it's some sort of trailing error from my indentation in the code preceding it but I can't spot any mistakes...

Here's the code:

 module Main where                                                                  
  g :: Float -> Float                                                                
  --your function here                                                               
  g x = cos(x^2)                                                                     

  --goldenSectionSearch                                                              
  goldenSS :: (Float -> Float) -> Float -> Float -> Float -> Float -> Float          
  goldenSS f a b c tau                                                               
    | (c-a) < tau * (abs b + abs x) = (c+a)/2                                        
    |f x > f b = let                                                                 
                  t1|(c - b) > (b-a) = goldenSS f b x c tau                          
                    |otherwise = goldenSS f a x b tau                                
                  in t1                                                              
    |otherwise = let                                                                 
                  t2|(c-b) > (b-a) = goldenSS f a b x tau                            
                    |otherwise = goldenSS f x b c tau                                
                  in t2                                                              
    where                                                                            
      let x                                                                          
            | (c-b) >  (b-a) = b + resphi*(c-b)                                      
            |otherwise = b - resphi*(b-a)                                            
            where resphi = 2 - phi where phi = (1+ sqrt 5)/2                         
        in x                                                                         

  --main                                                                             
  main = do                                                                          
          print x                                                                    
          print (g x)                                                                
            where                                                                    
              x = goldenSS g a ((a+b)/2) b tau                                       
                where                                                                
                  a = 2                                                              
                  b = 3                                                              
                  tau = 0.001      

any ideas?


Solution

  • The reason you're getting the parse error stems from the non-idiomatic usage of let and where bindings in your code.

    Haskell allows multiple syntactic structures for temporary bindings and pattern matching, but you're combining them in a rather strange and messy manner.

    To learn how to write the code cleaner and in a manner more usual for Haskell, I'd recommend looking up existing haskell libraries and programs (for example on hackage) to get a feel for how let and where bindings usually work. In general I find that for pure functions I almost exclusively use where (as opposed to let), but certain things are stylistic.

    As for this code, I modified it a bit to use where bindings instead of let, and it compiles and runs for me now. Even if you have to tweak it a bit to get it to compile for you, this overall structure is cleaner and less likely to give you parse errors:

    module Main where                                 
    
    g :: Float -> Float                                                      
    g x = cos(x^2)                                                           
    
    goldenSS :: (Float -> Float) -> Float -> Float -> Float -> Float -> Float 
    goldenSS f a b c tau                                        
      |(c-a) < tau * (abs b + abs x) = (c+a)/2                               
      |f x > f b = t1                         
      |otherwise = t2                                      
    
      where x | (c-b) >  (b-a) = b + resphi*(c-b)                  
              |otherwise = b - resphi*(b-a)    
    
            resphi = 2 - phi
    
            phi = (1+ sqrt 5)/2                         
    
            t1 |(c - b) > (b-a) = goldenSS f b x c tau                         
               |otherwise = goldenSS f a x b tau       
    
    
            t2 |(c-b) > (b-a) = goldenSS f a b x tau                            
               |otherwise = goldenSS f x b c tau  
    
    
    
    main =
      do                                                                          
        print x                                                                    
        print (g x)                                                                
      where x = goldenSS g a ((a+b)/2) b tau                                       
            a = 2                                                              
            b = 3                                                              
            tau = 0.001