2015-10-08 19 views
5

Haskell çalışarak, çıplak kemiklerİzin beyanı içinde bir vaka bildirimi için girinti ne kadar gereklidir?

Bu

a :: Bool 
a = case True of 
    True -> True 
    False -> False 

Works Ama

b :: IO Bool 
b = do 
    let b' = case True of 
     True -> True 
     False -> False 
    return b' 

çalıştığımda Yani

ghci>:l test.hs 
[1 of 1] Compiling Main    (test.hs, interpreted) 

test.hs:16:14: parse error on input ‘->’ 
Failed, modules loaded: none. 

almak için soyunmuş, tek bir davranış bulundu Ben

'yı deneyin.

Ve bu işler.

Ne? Niye ya? Bu durumda neden fazladan girintiye ihtiyacım var? Bu konuda bir şey bulamıyorum, çünkü bu anahtar kelime günlük dilde çok kısa ve yaygındır. Bu davranışı açıklayan bazı özellikler var mı?

+1

'let' bloğunun girintileme seviyesi,' let' sonrası ilk boşluk olmayan karakterde başlar.Yani 'True'' let' bloğunda bir yan tümce olarak yorumlanıyor; 'case' bloğu – luqui

cevap

7

Tam anlamıyla açıklamalardan yok, ancak bu Wikibook page sorunu açık bir şekilde açıklıyor.

bu basit gibi çalışır nedeni:

c = do 
    let c' = … 
     d = … 
     e = … 
    return c' 

Sizin True -> … ve False -> … yanlışlıkla ek değişkenler olarak yorumlanır bağlı kalmayı: gibi tek let-grubu üzerinden bağlanma birden çok değişkeni destekleyecek.

+0

'un içinde bir boşluk daha alacaktır. Ve burada Veri kurucularının büyük harf kullanımının bu gibi belirsizlikleri ortadan kaldırması gerektiğini düşündüm. Python ve diğer dillerle aynı anda çalışmayı denediğime inanıyorum. – user2085282

+2

"Veri yapıcıların büyük harf kullanımı bu gibi belirsizlikleri ortadan kaldırmaktır" Bu durumda buna güvenemezsiniz. Eğer bir desen eşleşmesi olsaydı şöyle olurdu: 'case… of {x ->…; _ ->…; } '? Bu durumda 'x' ve' _' geçerli değişken isimlerdir. (Contested örnek, biliyorum, ama yine de.) – Rufflewind

+4

Ve diğer şekilde de, 'Just Just f = ...' mükemmel bir beyan olduğunu. –

7

temel girinti kuralları aslında oldukça basittir: Bir blok başlangıç ​​anahtar kelimeler sonra

  • (where, let, do, case .. of) kalmış olabilir sonraki kelime başlar sütunu (not bu blokta yeni girişler
  • hatları önceki girdiyi
  • bir çizgi indente devam daha girintili olduğu gibi bir sonraki hat)
  • hatları tam olarak girintili d daha az önce o satırdan önce blok hakkına iç içe bloklar halinde
  • , dıştaki bloğuna kurallarını uygulamak, biter

Tricky örnek:

Senin durumunda
1 + case x of 
     A -> 45 -- note where "A" starts 
     B -> 10 -- same indentation: another case branch 
     + 2  -- more indented, so it's "10+2" 
    + 10  -- less indented, so it's "1+(case ...)+10" 

,

let b' = case True of 
    True -> True 
    False -> False 

iki iç içe geçmiş blok var, bunlardan biri let, diğeri case..of. let blokları b' sütununu kullanır. case..of bloğu aynı sütunu yeniden kullanmaya çalışır, ancak ilk önce kuralları en dıştaki bloğa uygulamanız gerekir. Yani True -> ... hattı aslında let bloğunun yeni bir girdisidir. Bu, ayrıştırma hatasını tetikler.