Berkat evaluasi malas, program Haskell tidak (hampir tidak bisa ) melakukan apa yang terlihat seperti yang dilakukannya.
Pertimbangkan program ini:
main = putStrLn (show (quicksort [8, 6, 7, 5, 3, 0, 9]))
Dalam bahasa yang bersemangat, pertama quicksortakan lari, lalu show, lalu putStrLn. Argumen fungsi dihitung sebelum fungsi tersebut mulai berjalan.
Di Haskell, justru sebaliknya. Fungsi tersebut mulai berjalan lebih dulu. Argumen hanya dihitung saat fungsi benar-benar menggunakannya. Dan argumen gabungan, seperti daftar, dihitung satu per satu, karena setiap bagian digunakan.
Jadi hal pertama yang terjadi dalam program ini adalah yang putStrLnmulai berjalan.
Implementasi GHC dari putStrLn bekerja dengan menyalin karakter dari argumen String ke dalam buffer keluaran. Tapi saat memasuki loop ini, showbelum berjalan. Oleh karena itu, saat akan menyalin karakter pertama dari string, Haskell mengevaluasi pecahan dari panggilan showdan yang quicksortdiperlukan untuk menghitung karakter itu . Kemudian putStrLnberalih ke karakter berikutnya. Jadi eksekusi ketiga functions- putStrLn, showdan quicksort- disisipkan. quicksortdieksekusi secara bertahap, meninggalkan grafik halangan yang tidak dievaluasi untuk mengingat di mana ia tinggalkan.
Sekarang ini sangat berbeda dari apa yang mungkin Anda harapkan jika Anda terbiasa dengan, Anda tahu, bahasa pemrograman lain yang pernah ada. Tidak mudah untuk memvisualisasikan bagaimana quicksortsebenarnya berperilaku di Haskell dalam hal akses memori atau bahkan urutan perbandingan. Jika Anda hanya dapat mengamati perilakunya, dan bukan kode sumbernya, Anda tidak akan mengenali apa yang dilakukannya sebagai quicksort .
Misalnya, versi C dari quicksort mempartisi semua data sebelum panggilan rekursif pertama. Dalam versi Haskell, elemen pertama dari hasil akan dihitung (dan bahkan dapat muncul di layar Anda) sebelum partisi pertama selesai dijalankan — bahkan sebelum pekerjaan apa pun diselesaikan greater.
PS Kode Haskell akan lebih seperti quicksort jika ia melakukan jumlah perbandingan yang sama dengan quicksort; kode seperti yang tertulis melakukan perbandingan dua kali lebih banyak karena lesserdan greaterditentukan untuk dihitung secara independen, melakukan dua pemindaian linier melalui daftar. Tentu saja pada prinsipnya mungkin bagi compiler untuk menjadi cukup pintar untuk menghilangkan perbandingan ekstra; atau kode dapat diubah untuk digunakan Data.List.partition.
PPS Contoh klasik dari algoritma Haskell ternyata tidak berperilaku seperti yang Anda harapkan adalah saringan Eratosthenes untuk menghitung bilangan prima.