2014-11-12 42 views
5

Geçtiğimiz günlerde bazı Haskell kodları yazdım ve hiçbir zaman sona ermiyor. Ben dikkatle kodumu incelendiğinde sonra sorun bu aynı kod OCaml son bulan bu yana Haskell tembellik ile ilgili bir şey olmalı sanırım aşağıdaki kod parçasınınBu Haskell kodu neden sonlandırılmıyor?

main :: IO() 
main = print $ let a = 10 in 
       let a = a in 
       a :: Int 

aşağı haşlanmış. Ancak, eğer kod hiç sonlandırma sorun olurdu yerine

main :: IO() 
main = print $ let a = 10 in 
       let b = a in 
       b :: Int 

aşağıdaki kodu yazdım. Orijinal kodda bu yana neden bulamıyorum, iki a iki değişken olarak kabul edilmelidir. Onların isimlendirilmesinin neden programın semantiği ile bir ilgisi olduğunu bilmiyorum.

cevap

15

konu OCaml aksine Haskell let bağlamaları varsayılan tarafından özyinelemelidir, olmasıdır. Yani let x = x in ... OCaml en let rec x = x in ... eşdeğerdir ve dairesel tanımıdır.

Haskell gölgeleme değişken adları (yani a birden çok kez tanımlayan) Bu nedenle kötü tarzı olarak kabul edilir ve hatta -Wall bayrak veya daha spesifik -fwarn-name-shadowing ile açabilirsiniz bir derleyici uyarı, vardır.

Bu varsayılan çünkü tembellik sayesinde dairesel değerleri (yerine sadece özyinelemeli fonksiyonlar) aslında yararlıdır OCaml daha Haskell daha mantıklı. let x = 1:x bize sadece normal bir listesi gibi kullanabilirsiniz 1 sonsuz listesini verir.

Aynı zamanda, bazı insanlar burada tam olarak neden olduğunuz için tam olarak böyle bir şeyden hoşlanmıyorlar: kodunuzda, bazı hatalar ve yazım hatalarını daha zor hale getiren, bilinçsiz sonsuz döngüleri tanıtmak mümkündür. zorunlu olarak, do-gösterimde yılında <- bağlamaları biraz tutarsız varsayılan olarak özyinelemeli değil vardır, çünkü bu da kafa karıştırıcı.

ikinci bağlanma (a = a)
+1

Durum <- 'ile çok daha kötüdür. – dfeuer

+0

@dfeuer: Ben görmedim '-XDoRec' veya GHC dokümanlar dışında' mdo' ... Ben kullandım – yatima2975

+0

yatima2975 @ 'önce rec' yoktur. Aslında bazı şeyleri çözmek için temiz bir yol. – Carl

5

diğerini gölgeler. İlk örnek

main = print $ let xyz = 10 in 
       let a = a in 
       a :: Int 

tam olarak eşdeğer (neredeyse) ve ben bu bir sonlandırmaz neden açıktır umut! Bu konuda sizi uyarmak için GHC'yi -fwarn-name-shadowing işaretini kullanarak (veya GHCi'ye :set -fwarn-name-shadowing girerek)

İlgili konular