Decomposing bitfield with Haskell: is recursion the only way to do this?
A more common way of "initializing" values on the first call is to define an inner worker function.

findPower :: Int -&gt; Int
findPower bitfield = go 0
    where go i = ... -- Note that the bitfield argument is still in scope


Recursion is the standard way to loop in Haskell (so much so that in lots of code you will find locally defined recursive functions named loop), but your code might be more terse without explicit recursion.

Here's my first pass at a rewrite of the findPower function using higher order functions.

findPower :: Int -&gt; Int
findPower i = last . takeWhile (&lt;= i) $ map (2^) [0..]


Note that this function still isn't total, i.e. it will fail when passed Ints &lt;= 0. Your version would recurse until 2^power overflows, whereas mine will fail fast with an empty list exception due to the use of last. It's considered good style to make your Haskell functions total, so here's my second pass.

findPower :: Int -&gt; Maybe Int
findPower 0 = Just 0
findPower i | i &lt; 0     = Nothing
            | otherwise = Just . last . takeWhile (&lt;= i) $ map (2^) [0..]


Using Maybe here is probably overkill, and in fact you probably want your program to crash when given bad input! Here's a final version.

findPower :: Int -&gt; Int
findPower i | i &lt; 0     = error "findPower: Can't find power of negative number"
            | i == 0    = 0
            | otherwise = last . takeWhile (&lt;= i) $ map (2^) [0..]


On this line | found = [flag] ++ ..., if you're adding a single element to the front of a list, this is just regular cons! Use | found = flag : ... instead.

You've defined a lot of constants in where clauses for your two functions which only get used once. Sometimes it can be helpful to give a name to something that might be non-obvious, but in this case it makes your code longer and arguably adds a bit of cognitive overhead to what are very simple transformations. For instance, I would consider this more readable.

getFlags currentBits flag | currentBits == flag = [flag]
                          | currentBits &gt; flag  = flag : getFlags (currentBits - flag) (flag `div` 2)
                          | otherwise           = getFlags currentBits (flag `div` 2)


In your definition of main, you can omit the type annotation from read line and the compiler will deduce you want an Int due to the type signature of bithelp. On its own this is a small change, but leveraging the type system in this way is entirely natural and reduces the number of changes you would have to make if, say, you changed your functions to operate on Integers.

See if this isn't more clear.

main = do putStrLn "Enter a positive integer:"
          nstr &lt;- getLine
          putStrLn "List of flags:"
          print $ bithelp (read nstr)


The last thing to do would be to eliminate the bithelp function by rewriting the getFlags function with a call to findPower inside of it, passed to an inner worker function. I'll leave that as an exercise to the reader.