2014-11-14 3 views
1

Вот моя функция:Создание функции Haskell, которая печатает и возвращает значение

foo :: Int -> Int 
foo i = do 
    putStrLn "Foo Function has run!" 
    return (i*2) 

выше имеет ошибку во время компиляции.

Я хочу, чтобы это было так, что если бы я сделал это:

bar = foo 6 

бар будет 12.

но когда функция первого запуска, он выводит строку «Foo функция бег!" Как я могу это сделать?

ответ

4

Вы должны сделать функцию функцией IO. Haskell строго соблюдает, что вы отделяете код, который делает IO от кода, который не:

foo :: Int -> IO Int 
foo i = do 
    putStrLn "Foo Function has run!" 
    return (i * 2) 

Вы могли бы извлечь это значение внутри другого IO функции:

main :: IO() 
main = do 
    bar1 <- foo 6 
    bar2 <- foo bar1 
    print (bar1, bar2) 

Причины, почему Haskell выбирает этот маршрут являются многие и разнообразные, но некоторые из важных (в определенном порядке):

  • Испытание. Любая чистая функция намного легче тестировать, потому что она всегда зависит только от ее входов, а не от состояния приложения
  • Equational reasoning. Это означает, что вы можете рассуждать о своем коде, как будто это просто причудливые математические функции. Вы можете перемешать свой код намного проще.
  • Оптимизация компилятора. Компилятор может выбирать, когда и как вызывать свою функцию, если у нее нет побочных эффектов, она может отсрочить вызов до конца, и она может сделать очень плотные внутренние петли в скомпилированном коде, которые работают намного быстрее.
  • Композиция. Система типа Haskell очень богата, и сегрегационные типы в этом режиме фактически позволяют писать больше абстракций, чем вы могли бы использовать на C#, Java или Python.
  • Четкость кода. Если вы видите, что функция просто возвращает значение, а не действие IO, вы сразу же знаете много о этой функции. Подпись этого типа является обещанием, что вам не нужно беспокоиться о том, что функция может нарушить ваше приложение. С другой стороны, если он возвращает действие IO, это означает, что вы должны быть более осторожными.
+0

Thats amazing, но что, если я не использовал Int, а вместо M.Map String Int. Я попробовал «IO M.Map String Int» и «IO (M.Map String Int)», но оба они порождают ошибки –

+0

@YahyaUddin Какие ошибки они производят? Второй пример, который вы опубликовали выше, должен работать нормально. Функция 'return' является полиморфной в своем аргументе и ее возвращаемом типе, она будет работать с любым типом, который вы ему даете. – bheklilr

+0

Я отредактировал сообщение, чтобы включить сообщение об ошибке –

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