There are a number of things wrong with your code, unfortunately. The first problem is the do
on the top line: you aren't using any monads, so you shouldn't have it at all. The rest of the code is trying to work in an imperative manner, but this (unsurprisingly) doesn't work in Haskell. In Haskell, every expression needs to have a result; for this reason, all if statements must be of the form if ... then ... else ...
. Similarly, every let binding must be of the form let ... in ...
; it's impossible to change the value of a variable, so if you left off the in
, nothing would happen. And because of this, each line let result = result ++ [3]
, if it could be executed, would try to make a list result
which consisted of all of its elements with a three at the end—in other words, a self-referential list! (The canonical example of such a thing is let ones = 1:ones in ones
to create a list whose tail is itself and thus contains only 1
s.)
So now the question is, what does your function want to do? You have four boolean conditions, and want to add a different element to your list for each one. There are a number of ways you could write this instead. One approach is
foo :: Integer -> Integer -> Integer
foo a b = let Coord x y = boo a b
checkAdd cond elem = if cond then (elem :) else id
in foldr (uncurry checkAdd) []
[(x > 0, 3), (y > 0, 5), (x > a, 7), (y > b, 9)]
First, we call boo
and look at the results. We then define a checkAdd
function, which has type checkAdd :: Bool -> a -> ([a] -> [a])
. If its first argument is true, then it returns a function which prepends its second argument to a list; otherwise, it returns a function which does nothing to a list. So checkAdd True 1 x == 1:x
, and checkAdd False 1 x == x
. The last line is admittedly a little mysterious, but it's not too bad. If you have a list fns = [f1,f2,...,fn]
of functions, and want to produce f1(f2(...(fn(x))...))
, then you can use foldr ($) x fns
. This fold is similar, except we have uncurry checkAdd
instead of $
; uncurry
causes a function to take a tuple instead of two arguments, and so when we foldr
it over the list, checkAdd
produces a function for each element. Then, each function is applied, and you arrive at the list you wanted. The reason we don't have ($) . uncurry checkAdd
is that $
is really just the identity function with low precedence; this makes sense, since $
's only purpose is to have really low precedence but not do anything.
Of course, this code looks completely different from what you had above, but that's part of what's interesting about trying out completely different languages :-)