В чем разница между чистым и нечистым в haskell? Когда вы делаете IO в haskell, что значит держать чистые и нечистые предметы отдельно?
В чем разница между чистым и нечистым в haskell?
Ответ 1
По существу, вы хотите сохранить как можно меньше кода в "нечистой секции". Код, написанный в монаде IO, навсегда испорчен отсутствием безопасности. Функция с сигнатурой IO Int
вернет целое число в монаде IO, но на вершине этого можно отправить ядерные ракеты на Луну. У нас нет возможности узнать, не изучая каждую строку кода.
Например, скажем, вы хотите написать программу, которая берет строку и добавляет к ней "чувак".
main = do
line <- getLine
putStrLn $ line ++ ", dude"
Некоторые части кода должны быть в монаде IO, потому что у них есть побочные эффекты. Сюда входят getLine и putStrLn. Однако объединение двух строк не происходит.
main = do
line <- getLine
putStrLn $ addDude line
addDude input = input ++ ", dude"
Подпись addDude показывает, что она чиста: String -> String
. Нет IO
здесь. Это означает, что мы можем предположить, что addDude будет вести себя как минимум таким образом. Он примет одну строку и вернет одну строку. Невозможно иметь побочные эффекты. Это невозможно, чтобы взорвать луну.
Ответ 2
Чистота просто означает отсутствие побочных эффектов (чтение с диска, перемещение руки робота и т.д.)
Отделение чистого от нечистых функций означает, что вы можете узнать больше о том, что будет делать ваш код. Например, когда вы говорите 1 + 2
, вы точно знаете его тип (Int -> Int -> Int
), что единственное, что он делает, это взять два числа и произвести третье число. Если его тип Int -> Int -> IO Int
, он может перемещать руку робота каждый раз, когда он добавляет два числа.
Хорошее начальное место для основ Haskell можно найти здесь: http://learnyouahaskell.com/introduction#so-whats-haskell
Ответ 3
Все в Хаскелле чисто. То, что вы читаете, скорее всего связано с кодом внутри IO mondad и снаружи. Как только вы помещаете что-то в монашу IO, она никогда не сможет "убежать" - вы должны остаться в монаде IO. Поэтому монада IO имеет тенденцию "вторгаться" в ваш код - если у вас есть вещь, которая возвращает IO, тогда любой код, который вызывает это, также должен возвращать IO и т.д. Поэтому лучше использовать монаду IO только там, где это необходимо, на максимально возможном уровне программы, и выделять любые части вычислений, которые чисты в чистые функции.