2009-06-24 13 views
7

F # (Visual Studio 2010 beta 1) ile uğraşıyordum ve kullanıcıya 2 sayı ve bir operatör girmesini ve ardından çalıştırmasını isteyen küçük bir konsol komut dosyası yazdım. Küçük, ama can sıkıcı bir şey dışında iyi çalışıyor: bazen printfn yönergeleri yok sayılıyor. Durumun gerçekten görüldüğünü görmek için koda boşluk bıraktım.F # garip printfn sorunu

kod parçacığı:

let convert (source : string) = 
    try System.Int32.Parse(source) 
    with :? System.FormatException -> 
     printfn "'%s' is not a number!" source; 
     waitForExitKey(); 
     exit 1 

let read = 
    printfn "Please enter a number."; 
    System.Console.ReadLine 

let num1 : int = read() |> convert // the printfn in the read function is run... 
let num2 : int = read() |> convert // ... but here is ignored 

Bu tabii tam kaynağı değildir, ama bu yeterli olacak düşünüyorum. Tam kaynağa ihtiyacınız varsa sadece bana bildirin.

Bu yüzden sorum sorum oldukça basit: printfn ile bu soruna neden olan nedir? Yanlış bir şey mi yapıyorum? peşin

sayesinde ShdNx

cevap

15

This page neler kısmi açıklaması olduğunu ancak kısa ve tatlı versiyonu olduğunu F # olacak Parametre almazsa beyan üzerindeki herhangi bir değeri çalıştırır. read yana

let read = 
    printfn "Please enter a number." 
    System.Console.ReadLine 

herhangi bir parametre, onun beyanı üzerine derhal infaz alıp tanımlayıcı read işlevin dönüş değeri bağlar etmez.

Bu arada, dönüş değeriniz (unit -> string) türünde bir işlev olarak gerçekleşir. Bu, tüm parametrelerini geçmediği takdirde, F # otomatik olarak curries functions sonucunu verir. ReadLine, bir birim parametresi bekler, ancak iletilmediğinden, 'u ReadLine işlevinin kendisine bağlarsınız. aşağıdaki gibi

çözüm: read yana

let read() = // read takes one unit parameter 
    printfn "Please enter a number." 
    System.Console.ReadLine() // pass paramter to ReadLine method 

bir parametre olarak, adı verilen yeniden değerlendirilen her zaman alır. Ayrıca, bir parametreyi ReadLine'a geçiriyoruz, aksi takdirde ReadLine işlevini bir değer olarak döndüreceğiz.

+0

Çok teşekkür ederim! Ne yazık ki Ray daha hızlıydı, bu yüzden cevabını kabul ettim. Ama bunu açıkça yaptığına çok sevindim. Tekrar teşekkürler! – ShdNx

+0

Katılıyorum! Daha açık bir açıklama için +1! –

7

Bunun kafa karıştırıcı olabileceğini anlıyoruz. Örneğinizde, printfn, düşündüğünüzden daha önce çalışır. Aslında, read() numaralı çağrı olmadan bile çalışır, yani son iki satırı yorumlayacak ve yine de yazdırılan bir mesaj göreceksiniz. Bu, ilk örnekte olduğu gibi bir tanımlayıcı bir işlev bağlama yerine "yeniden" işlevi oluşturun

let read() = 
    printfn "Please enter a number."; 
    System.Console.ReadLine() 

:

niyetinin böyle bir şey olduğunu düşünüyorum.

Bir not olarak

, sadece yazabilirsiniz işte yarı iki nokta üst üste kullanılması isteğe bağlıdır:

let read() = 
    printfn "Please enter a number." 
    System.Console.ReadLine() 
+0

Çok teşekkür ederim, sanırım şimdi anlıyorum! Yarı-virgül kullanıyorum çünkü her satırdan sonra otomatik olarak noktalı virgül eklerim ve hiç göremezsem beni rahatsız eder ... :-) – ShdNx