strange haskell parse error - haskell

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?

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

Related

To make the GCD code nicer and less verbose

I am using Euclid's algorithm for computing  GCD(M,N), the greatest common divisor of two integers M and N.
Though this code works well, I felt it's bit cumbersome to wrap it with max, min, and abs for both variables (a, b).
Can anyone suggest a better way to make the code less verbose?
I found the built-in gcd type was defined as gcd :: Integer a => a -> a -> a, but I cannot simply use it. What do I need to change in order to reuse the type definition?
gcd2 :: Int -> Int -> Int
gcd2 a b =
let x = max (abs a) (abs b)
y = min (abs a) (abs b)
in if (y == 0) || (x == y && x > 0)
then x
else gcd2 y (x-y)
Well, inspired by chi, I changed the code as below.
gcd3 :: Int -> Int -> Int
gcd3 a b | a < 0 = gcd3 (-a) b
| b < 0 = gcd3 a (-b)
| b > a = gcd3 b a
| b == a || b == 0 = a
| otherwise = gcd3 b (a-b)
This is the best I can do. :)
As suggested by chi in his answer, to avoid using abs in each recursive step I’d define a GCD local function where you pass the absolute value of the arguments. This way the implementation is pretty straightforward:
gcd :: Int -> Int -> Int
gcd a b = gcd' (abs a) (abs b)
where gcd' a 0 = a
gcd' a b = gcd' b (a `mod` b)
You can look at how it is implemented in base:
gcd :: (Integral a) => a -> a -> a
gcd x y = gcd' (abs x) (abs y)
where gcd' a 0 = a
gcd' a b = gcd' b (a `rem` b)

Haskell code won't compile with certain variable names

I'm getting an error from GHCi that I can't explain. I'm working with the following code (the vast majority of which is seemingly-irrelevant to the issue, but I can't replicate the issue with less code; commented-out lines are ones that I would like to add to replace the dummy in 0 lines)
import Linear
apply x f = f x
pos xs = -- smallest i where xs!!i > 0, else length xs
let aux xs n = case xs of
x:t -> if x > 0 then n
else aux t (n+1)
[] -> n
in aux xs 0
optimize d opt d_opt funs d_funs x0 p0 eps =
let n = length funs in
let aux x p f_best = let feas = map (apply x) funs in
let i = pos feas in
let (g,a,f_best) =
if i == n then
let g = d_opt x in
let g' = p !* g in
let prod = g `dot` g' in
let g = g / (sqrt prod) in
let f_best = min (opt x) f_best in
let a = (opt x - f_best) / (sqrt prod) in
(g,a,f_best)
else
let g = (d_funs!!i) x in
let g' = p !* g in
let prod = g `dot` g' in
let g = g / (sqrt prod) in
let a = ((funs!!i) x) / (sqrt prod) in
(g,a,f_best)
in
let b = (1+d*a)/(d+1) in
let b' = 2/(1+a) in
let b'' = (1-a^2)*(d^2)/(d^2-1) in
let h = p !* g in
let y = x - b*g in
-- let q = (p - g'*(transpose g')*b*b')*b'' in
-- aux y q f_best
0
-- in aux x0 p0 (1/0)
in 0
This code causes GHCi to throw six errors, including highlighting the p in let h = p !* g in; however, when I change that line to let g = p !* g in it goes through. Unfortunately, doing this and then uncommenting the next line (let x = x - b*g in) causes the same errors to be thrown (including highlighting the p in the same spot).
p and p0 are supposed to be (n-by-n) square matrices using the Linear package, while g, x and x0 are supposed to be (n-by-1) vectors; d is an integer, opt is a linear function on n-space, funs is a list of convex functions on n-space, d_opt and d_funs are the respective gradients, eps is real.
Any help with getting this to compile would be greatly appreciated. Thanks!
Edit: here is one of the error messages. There are similar ones for let g = d_opt x, let f_best = min (opt x) f_best, let g = (d_funs!!i) x, let a = ((funs!!i) x) / (sqrt prod), and let b = (1+d*a)/(d+1).
Lenstra.hs:57:34: error:
• Occurs check: cannot construct the infinite type: a1 ~ m a1
Expected type: m (m a1)
Actual type: m (m (m a1))
• In the first argument of ‘(!*)’, namely ‘p’
In the expression: p !* g
In an equation for ‘h’: h = p !* g
• Relevant bindings include
h :: m a1 (bound at Lenstra.hs:57:30)
b'' :: m a1 (bound at Lenstra.hs:56:30)
b' :: m a1 (bound at Lenstra.hs:55:30)
b :: m a1 (bound at Lenstra.hs:54:30)
g :: m a1 (bound at Lenstra.hs:37:31)
a :: m a1 (bound at Lenstra.hs:37:33)
aux :: m a1 -> m (m (m a1)) -> p8 -> p9 (bound at Lenstra.hs:35:9)
(Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)
|
57 | let h = p !* g in
| ^
Failed, no modules loaded.
There are several errors:
Where the integer d is used as a float, you need to use fromIntegral, so for example: b = (1 + fromIntegral d * a)/(fromIntegral d + 1)
Scalar multiplication/division of vectors and matrices can't use * and /. You must use the *^, ^*, and ^/ operators for vectors and !!* and !!/ for matrices.
Pointwise sums and differences of vectors and matrices can't use + and -. You must use ^+^ and ^-^ for vectors and !+! and !-! for matrices.
For a vector g', transpose g' isn't going to work, so g' * transpose g' doesn't have a prayer. Use outer g' g' to get the matrix resulting from the product of g' as a column vector with g' as a row vector, if that's what you're trying to do.
There was no g' in scope where q is defined. Maybe you wanted to return g' from your if statement?
let g = some expression with g is not going to work, as you'll create a recursive definition that loops forever. You'll need to use a fresh variable -- you've done this correctly in some places but not in others.
There's also a significant logic error, at least in the version with your commented statements uncommented. The function aux never returns anything other than a tail call to aux, so it will necessarily loop forever. I don't even know what type it's supposed to return. You need some stopping condition (probably returning f_best or something).
You will find it helpful to add type signatures to optimize and its aux function to keep these errors under control. The following type-checks but still contains several bugs (infinite loops, etc.):
import Linear
import Data.Vector (Vector)
apply x f = f x
pos :: (Ord a, Num a) => [a] -> Int
pos xs = -- smallest i where xs!!i > 0, else length xs
let aux xs n = case xs of
x:t -> if x > 0 then n
else aux t (n+1)
[] -> n
in aux xs 0
type Matrix a = Vector (Vector a)
optimize
:: Integer
-> (Vector Double -> Double)
-> (Vector Double -> Vector Double)
-> [Vector Double -> Double]
-> [Vector Double -> Vector Double]
-> Vector Double
-> Matrix Double
-> Double
-> a
optimize d opt d_opt funs d_funs x0 p0 eps =
let n = length funs in
let aux
:: Vector Double
-> Matrix Double
-> Double
-> a
aux x p f_best = let feas = map (apply x) funs in
let i = pos feas in
let g :: Vector Double
(g,g',a,f_best) =
if i == n then
let g = d_opt x in
let g' = p !* g in
let prod = g `dot` g' in
let g = g ^/ (sqrt prod) in -- **LOOP**
let f_best = min (opt x) f_best in
let a = (opt x - f_best) / (sqrt prod) in
(g,g',a,f_best)
else
let g = (d_funs!!i) x in
let g' = p !* g in
let prod = g `dot` g' in
let g = g ^/ (sqrt prod) in -- **LOOP**
let a = ((funs!!i) x) / (sqrt prod) in
(g,g',a,f_best)
in
let b = (1+fromIntegral d*a)/(fromIntegral d+1) in
let b' = 2/(1+a) in
let b'' = (1-a^2)*(fromIntegral d^2)/(fromIntegral d^2-1) in
let h = p !* g in
let y = x ^-^ b*^g in
let q = (p !-! outer g' g' !!* (b*b')) !!* b'' in
aux y q f_best
in aux x0 p0 (1/0)
Finally, when you get this running, you might want to submit it to the Code Review Stack Exchange, along with an explanation of the algorithm and some running examples. There are lots of stylistic improvements that I think could make it make it more idiomatic.

Instance for function with several classes

I want to realize power function for my custom data type. I mean power (^) which has following signature:
(^) :: (Num a, Integral b) => a -> b -> a
And I mean that my data type MyData should be instance of Num, so I could write
x :: MyData
...
y = x ^ b
where b is some Integral. It's very easy when we need function of one class like
(+), (-), (*) :: (Num a) => a -> a -> a
We just write
instance Num MyData where
(*) x y = someFunc x y
But I have no idea how to define it taking into account that there is also Integral b. That syntax should be like
instance (Integral b) => Num MyData b where
(^) x y = someFunc x y
But I've tried a hundred of such variations and nothing works. Hours of googling also didn't help.
You don't have to do anything to define (^) for your data type; if your type has a Num instance, you get x ^ b for free, because (^) is defined for any type with a Num instance. (It basically just calls * a lot.)
Note that (^) is not a member of Num or Integral; it's just a standalone function whose type is constrained by both classes.
From https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Real.html#%5E
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
x0 is your MyData value; the only thing (^) ever does with x0 (by virtue of it being passed as the x argument to f or g) is to multiply it by itself, so technically (^) will work as long as you have defined (*) in your Num instance.

Haskell - Problems in the Mandelbrot drawer [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
So, as a beginner, I thought I would work on a horribly, awefully terrible version of the mandelbrot set project. In this pitiful case, the set is drawn with text (Shreik!) into a text file. Because I wanted some practice with some numerical coding, I have designed the worst complex number system in existance. I can't spot the problem in the code - the one that draws a band instead of a mandelbrot set. Here it is (don't look at it too long or you could die from over expossure to noob-ioactivity):
-- complex numbers, test for mandelbrot set
----------------- Complex Numbers
data C = Complex Float Float -- a + bi
deriving Show
data Mandelbrot = Possible -- if thought to be in mandelbrot set
| Not Integer -- this Integer is iterations before |z| > 2 in z=z^2+c
deriving Show
complexReal :: C -> Float
complexReal (Complex n _) = n
complexImaginary :: C -> Float
complexImaginary (Complex _ n) = n
modulus :: C -> Float
modulus (Complex n m) = sqrt ((n^2) + (m^2))
argument :: C -> Float --returns in radians
argument (Complex m n) | n < 0 && m < 0 = pi + (argument (Complex (0-m) (0-n)))
| m < 0 = (pi / 2) + (argument (Complex (0-m) n))
| n < 0 = ((3 * pi) / 2) + (argument (Complex m (0-n)))
| otherwise = atan (n / m)
multComplex :: C -> C -> C
multComplex (Complex m n) (Complex x y) = Complex ((m*x)-(n*y)) ((m*y)+(n*x))
addComplex :: C -> C -> C
addComplex (Complex m n) (Complex x y) = Complex (m + x) (m + y)
----------------- End Complex numbers
----------------- Mandelbrot
inMandelbrot :: C -> Mandelbrot
inMandelbrot c = inMandelbrotTest (Complex 0 0) c 0
--(z, c, i terations) with z=z^2+c, c is plotted on set map if z is bound
inMandelbrotTest :: C -> C -> Integer -> Mandelbrot
inMandelbrotTest z c i | (modulus z) > 2 = Not i -- too large
| i > 100 = Possible -- upper limit iterations
| otherwise = inMandelbrotTest (addComplex (multComplex z z) c) c (i+1)
possiblyInMandelbrot :: Mandelbrot -> Bool
possiblyInMandelbrot Possible = True
possiblyInMandelbrot _ = False
mandelbrotLine :: [C] -> String
mandelbrotLine [] = "\n"
mandelbrotLine (n:x) | possiblyInMandelbrot (inMandelbrot n) = "#" ++ mandelbrotLine x
mandelbrotLine (_:x) = " " ++ mandelbrotLine x
mandelbrotFeild :: [[C]] -> String
mandelbrotFeild [[]] = ""
mandelbrotFeild (n:x) = (mandelbrotLine n) ++ (mandelbrotFeild x)
-----------------End Mandelbrot
---------------- textual output
feildLine :: Float -> Float -> Float -> Float -> [C] -- start R, end R, i, increment x
feildLine s e i x | s > e = []
| otherwise = [(Complex s i)] ++ feildLine (s+x) e i x
feildGenerate :: Float -> Float -> Float -> Float -> Float -> [[C]] -- start R, end R, start i, end i, increment x
feildGenerate sr er si ei x | si > ei = [[]]
| otherwise = [(feildLine sr er si x)] ++ (feildGenerate sr er (si+x) ei x)
l1 :: String
l1 = mandelbrotFeild (feildGenerate (-3) 3 (-3) 3 0.05)
---------------- End textual output
main = do
writeFile "./mandelbrot.txt" (l1)
As you can see (or can't if you didn't look) there are some unused functions for my Complex numbers. Is there hope doctor?
Summary:
Why does this draw a band instead of the mandelbrot set?
Found your bug:
addComplex :: C -> C -> C
addComplex (Complex m n) (Complex x y) = Complex (m + x) (m + y)
It's really that simple. You have a trivial typo.
Some other suggestions:
Use Double rather than Float. For this example, it seems to give visibly more accurate results.
[x] ++ y is the same thing as x : y.
It is traditional to write x : xs rather than x : y. This makes it clear that one is a list element, the other is a list.
You can import Data.Complex to get complex-number arithmetic - but of course, you are writing this code for the purpose of learning, so that's fine.
If you define instance Num C where..., then you would be able to write z*z + c rather than addComplex (mulComplex z z) c. It's prettier to read - if you know how to write instances yet...
You can't spell "field". ;-)

Mapping which holds and passes previous result

When solving system of linear equations by Tridiagonal matrix algorithm in Haskell I met following problem.
We have three vectors: a, b and c, and we want to make a third vector c' which is a combination of them:
c'[i] = c[i] / b[i], i = 0
c'[i] = c[i] / (b[i] - a[i] * c'[i-1]), 0 < i < n - 1
c'[i] = undefined, i = n - 1
Naive implementation of the formula above in Haskell is as follows:
calcC' a b c = Data.Vector.generate n f
where
n = Data.Vector.length a
f i =
| i == 0 = c!0 / b!0
| i == n - 1 = 0
| otherwise = c!i / (b!i - a!i * f (i - 1))
It looks like this function calcC' has complexity O(n2) due to recurrence. But all we actualy need is to pass to inner function f one more parameter with previously generated value.
I wrote my own version of generate with complexity O(n) and helper function mapP:
mapP f xs = mapP' xs Nothing
where
mapP' [] _ = []
mapP' (x:xs) xp = xn : mapP' xs (Just xn)
where
xn = f x xp
generateP n f = Data.Vector.fromList $ mapP f [0 .. n-1]
As one can see, mapP acts like a standard map, but also passes to mapping function previously generated value or Nothing for first call.
My question: is there any pretty standard ways to do this in Haskell? Don't I reinvent the weel?
Thanks.
There are two standard function called mapAccumL and mapAccumR that do precisely what you want.
mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
mapAccumR :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
Basically, they behave like a combination of fold and map.
map f = snd . mapAccumL (\_ x -> (() , f x) ()
foldl f b = fst . mapAccumL (\b x -> (f b x, () ) b
If you use Data.Array, which is lazy, you can express the recurrence directly by referring to c' while defining c'.
Following code seems to be the simplest implementation of formula above in my case:
import qualified Data.Vector.Generic as V
calcC' a b c = V.postscanl' f 0.0 $ V.zip3 a b c
where
f c' (a, b, c) = c / (b - a * c')
Thanks to the authors of Vector who added helpfull postscanl' method.

Resources