Son zamanlarda Haskell öğrenmeye başladım çünkü fonksiyonel programlama hakkındaki bilgilerimi genişletmek istedim ve bunu şimdiye kadar gerçekten sevdiğimi söylemeliyim. Şu anda kullandığım kaynak Çoğul Görüş'teki 'Haskell Fundamentals Bölüm 1' dersidir. Ne yazık ki aşağıdaki kod hakkında öğretim elemanının belirli bir alıntı anlamakta biraz zorluk var ve çocuklar konuya biraz ışık tutabileceğini umuyordum.
Refakatçi Kodu
helloWorld :: IO ()
helloWorld = putStrLn "Hello World"
main :: IO ()
main = do
helloWorld
helloWorld
helloWorld
Alıntı
Bir do-bloğunda aynı GÇ eylemine birden çok kez sahipseniz, eylem birden çok kez çalıştırılır. Bu program, 'Merhaba Dünya' dizesini üç kez yazdırır. Bu örnek putStrLn
, bunun yan etkileri olan bir işlev olmadığını göstermeye yardımcı olur . Değişkeni putStrLn
tanımlamak için işlevi bir kez çağırırız helloWorld
. Dizeyi putStrLn
yazdırmanın bir yan etkisi olsaydı, yalnızca bir kez yazdırırdı ve helloWorld
ana do-blokta tekrarlanan değişkenin hiçbir etkisi olmazdı.
Diğer programlama dillerinin çoğunda, böyle bir program 'Merhaba Dünya'yı yalnızca bir kez basar, çünkü putStrLn
işlev çağrıldığında yazdırma gerçekleşir . Bu ince ayrım genellikle yeni başlayanları tetikler, bu yüzden bunu biraz düşünün ve bu programın neden 'Merhaba Dünya' putStrLn
yı üç kez yazdırdığını ve işlev yazdırma işlemini bir yan etki olarak yapsa neden yalnızca bir kez yazdırdığını anladığınızdan emin olun .
Ne anlamadım
Benim için 'Merhaba Dünya' dizesinin üç kez basılması neredeyse doğal görünüyor. helloWorld
Değişkeni (veya işlevi?) Daha sonra çağrılan bir tür geri arama olarak algılarım . Anlamadığım şey, nasıl putStrLn
bir yan etkisi olsaydı, dizenin sadece bir kez basılmasına neden olur. Ya da neden diğer programlama dillerinde sadece bir kez basılacağı.
Diyelim ki C # kodunda, şöyle görüneceğini varsayıyorum:
C # (Keman)
using System;
public class Program
{
public static void HelloWorld()
{
Console.WriteLine("Hello World");
}
public static void Main()
{
HelloWorld();
HelloWorld();
HelloWorld();
}
}
Eminim oldukça basit bir şeyi gözden kaçırıyorum ya da terminolojisini yanlış yorumluyorum. Herhangi bir yardım büyük mutluluk duyacağız.
DÜZENLE:
Cevaplarınız için hepinize teşekkürler! Yanıtlarınız bu kavramları daha iyi anlamama yardımcı oldu. Henüz tam olarak tıklandığını sanmıyorum, ancak konuyu gelecekte tekrar ziyaret edeceğim, teşekkür ederim!
putStrLn
etmez bir yan etkisi vardır; kaç kez çağırırsanız arayın bağımsız değişken için aynı GÇ eylemini döndürür . "Hello World"
putStrLn
helloworld
baskılar o bir eylem olmaz Hello world
; Bu tarafından döndürülen değeri olacaktır putStrLn
sonra bu baskılı Hello World
(yani, ()
).
helloWorld = Console.WriteLine("Hello World");
. Sadece içerirler Console.WriteLine("Hello World");
içinde HelloWorld
işleve yürütülecek her HelloWorld
çağrılır. Şimdi düşün helloWorld = putStrLn "Hello World"
yapar helloWorld
. İçerdiği bir IO monadına atanır ()
. Bir kez bağladıktan >>=
sonra, ancak o zaman faaliyetini gerçekleştirir (bir şeyler yazdırır) ve size ()
ciltleme operatörünün sağ tarafında verir.
helloWorld
C # 'da bir alan veya değişken gibi sabit olmayı düşünün . Uygulanmakta olan bir parametre yokhelloWorld
.