I've got a function that looks like this:
outputDelayCo :: Maybe Int -> (Event -> ByteString) -> [Event] -> Int -> IO ()
outputDelayCo Nothing = outputDelay Nothing
outputDelayCo (Just 1) = do exitSuccess
outputDelayCo (Just n) = outputDelay (Just (n-1))
I get this error:
Couldn't match expected type ‘(Event -> ByteString)
-> [Event] -> Int -> IO ()’
with actual type ‘IO a0’
In a stmt of a 'do' block: exitSuccess
In the expression: do { exitSuccess }
I can fix it by doing this, but it's much uglier:
outputDelayCo :: Maybe Int -> (Event -> ByteString) -> [Event] -> Int -> IO ()
outputDelayCo Nothing a b c = outputDelay Nothing a b c
outputDelayCo (Just 1) _ _ _ = do exitSuccess
outputDelayCo (Just n) a b c = outputDelay (Just (n-1)) a b c
I understand why there's an error: do exitSuccess is gonna have an IO a return type, so the types don't match up on that pattern. But what's the right/elegant way to do this?
Use a lambda for the exitSuccess
line:
outputDelayCo (Just 1) = \_ _ _ -> exitSuccess
Note that the do
is also redundant in that case as do foo
is equivalent to foo
. do
notation is only useful when you have a sequence of things to do.
Other than pattern matching, you can use multiple calls to const
:
outputDelayCo (Just 1) = const . const . const $ exitSuccess
This keeps things pointfree, if you're into that sort of thing, but I would argue that a lambda like Ganesh suggests is obvious more immediately than this solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With