Я пытаюсь глубже понять лень в Хаскеле.
Сегодня я представлял себе следующий фрагмент:
data Image = Image { name :: String, pixels :: String }
image :: String -> IO Image
image path = Image path <$> readFile path
Привлекательность здесь в том, что я мог бы просто создать экземпляр Image и передать его; если мне понадобятся данные изображения, они будут читаться лениво, в противном случае можно было бы избежать затрат времени и памяти на чтение файла:
main = do
image <- image "file"
putStrLn $ length $ pixels image
Но так ли это на самом деле? Как лень совместима с IO? Будет ли вызываться readFile независимо от того, получу ли я доступ к pixels image
, или среда выполнения оставит этот thunk без оценки, если я никогда не обращусь к нему?
Если изображение действительно читается лениво, то возможно ли, что операции ввода-вывода могут происходить не по порядку? Например, что если сразу после вызова image
я удалил файл? Теперь вызов putStrLn ничего не найдет, когда он попытается прочитать.