I’ve simplified the functions in question. I’m having trouble constructing a list inside a monad. I suspect a precedence problem.
newtype Boundary = MkBoundary Integer
testFunc :: [Boundary] -> [Maybe Integer]
testFunc (MkBoundary x:xs)
| (even x) = Just x : testFunc xs
| otherwise = Nothing : testFunc xs
testFunc _ = []
This works as expected. But I need to work in a monad. I’ll use IO for this example
testFunc :: [Boundary] -> IO [Maybe Integer]
testFunc (MkBoundary x:xs)
| (even x) = return $ Just x : testFunc xs
| otherwise = return $ Nothing : testFunc xs
testFunc _ = []
No matter how I try to manipulate precedence, this breaks.
test.hs:6:35:
Couldn't match expected type `[Maybe Integer]'
with actual type `IO [Maybe Integer]'
In the return type of a call of `testFunc'
In the second argument of `(:)', namely `testFunc xs'
In the second argument of `($)', namely `Just x : testFunc xs'
Failed, modules loaded: none.
What I am trying to accomplish is a constructing a list, then returning it to IO. What am I doing wrong?
The problem is that
testFunc xsreturns anIO [Maybe Integer], and you are using it as the tail of a list as if it were a[Maybe Integer]. You need to extract:Or, a more succinct way of saying the same thing:
(
(<$>)is fromControl.Applicativeand has typespecialized to
IO. It applies a function to the value “inside” a monadic computation.)Oh, also what missingno said 🙂