Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell - pattern matching and exitSuccess

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?

like image 730
Emoses Avatar asked Jan 09 '23 22:01

Emoses


2 Answers

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.

like image 80
GS - Apologise to Monica Avatar answered Jan 12 '23 10:01

GS - Apologise to Monica


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.

like image 38
bheklilr Avatar answered Jan 12 '23 12:01

bheklilr