2014-08-29 3 views
4

У меня есть функция, которая выглядит следующим образом:Haskell - сопоставление с образцом и ExitSuccess

outputDelayCo :: Maybe Int -> (Event -> ByteString) -> [Event] -> Int -> IO() 
outputDelayCo Nothing = outputDelay Nothing 
outputDelayCo (Just 1) = do exitSuccess 
outputDelayCo (Just n) = outputDelay (Just (n-1)) 

Я получаю эту ошибку:

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 } 

я могу это исправить, делая это, но это намного уродливее:

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 

Я понимаю, почему есть ошибка: сделать ExitSuccess собирается иметь IO тип возврата, так что типы не совпадают по этому погладить крачки. Но каков правильный/элегантный способ сделать это?

ответ

6

Использование лямбды для exitSuccess линии:

outputDelayCo (Just 1) = \_ _ _ -> exitSuccess 

Обратите внимание, что do также излишняя в этом случае, как do foo эквивалентно foo. do Обозначение полезно только в том случае, если у вас есть последовательность действий.

2

Кроме сопоставления с шаблоном, вы можете использовать несколько вызовов const:

outputDelayCo (Just 1) = const . const . const $ exitSuccess 

Это держит вещи pointfree, если вы в таком роде вещи, но я бы сказал, что лямбда, как Ганеш предлагает это очевидно, сразу же, чем это решение.

Смежные вопросы