Soru GHCi “let” - ne yapar?


Takdir edersiniz, birileri GHCi'de "izin" in ne yaptıklarına dair dokümanlar gösterebilir, ya da bunu başarısızlıkla sonuçlandırabilir, ikna edici bir şekilde açıklayabilir :-).

Anlayabildiğim kadarıyla, “let” (“in” olmadan) kendi başına Haskell dilinin bir parçası değildir ve öte yandan, kolon tarafından öncelenmediği için GHCI komutu da görünmez. .


25
2017-12-27 09:09


Menşei


Kısa cevap: let (olmadan in) olduğu Haskell dilinin bir parçası, bir do blok (ve GHCi'de yazmak, IO monad). - MasterMastic


Cevaplar:


GHCi'de programlama yaparken, IO monadındaki programlama ile do sözdizimi, mesela doğrudan IO eylemi veya benzeri monadic bağlama sözdizimini kullanın r <- someIOFun.

let ayrıca bir parçasıdır do böylece bunu da kullanabilirsiniz. Sanırım içine çıldırmış olmak let .. in <rest of the computation>Örneğin, bunu yaptığınızda:

ghci> let a = 1
ghci> someFun
ghci> someFun2

Gibi:

let a = 1 in
do someFun
   someFun2

29
2017-12-27 09:19



Sadece o değil IO () ama herhangi IO tip eylem IO a. - Satvik
Tamam, bu mantıklı ve GHCi'nin Haskell'e izin vermesine izin veriyor. - gwideman
let olmadan in bir blok içinde izin verilir ve verdiğiniz örnekle eşdeğer değildir (cf. stackoverflow.com/questions/8274650/...) - SwiftsNamesake
Bu çaresizlik kelimesi beni biraz attı. Garip olduğunu düşündüm. Ne anlama geldiği hakkında hiçbir fikrim yoktu. - jrahhali


İşte ilgili bölüm belgeleme.

GHCI ifadeleri IO hesaplama olarak yürütülür. Yani let İçinde sahip olduğunuzla aynı IO kullanarak non-IO ifadesini bağladığınız monad let.


11
2017-12-27 09:14



Dokümanları işaret ettiğin için teşekkürler, bunu bulamadım. Bir yan yorum olarak, bu dokümanın daha çok hayal kırıklığı yaratıyor. Yeni kullanıcıların karşılaşması, Haskell kavramlarının başlamasıyla ilgili derslerde sık sık sunulduğundan hemen hemen izin verir, ancak bir haskell kaynak dosyasına kopyalandığında işe yaramamış ve monadların anlaşılmasının çok yararlı olmadığı varsayımları vardır. Yine de, burada cevapların toplanmasıyla, en azından bu özelliklerin nasıl birbirine uyduğunu görüyorum. - gwideman
@gwideman Evet, bunu anlıyorum. Ghci ifadeleri olarak yazdıklarınızı doğrudan bir hs dosyasında kopyalayamazsınız ve çalışmalarını beklersiniz. İyi yapabilirsin main = do <your ghci statements>. Ghci'nin bir deyimin çıktısını çıktı olarak yazdırması her zaman beklendiği gibi çalışmayabilir. Showörneği. - Satvik


Daha fazla kod-aşağı detaylar için, bu yorum TcRnDriver.lhs aydınlatıcı olabilir:

--------------------------------------------------------------------------
                Typechecking Stmts in GHCi

Here is the grand plan, implemented in tcUserStmt

        What you type The IO [HValue] that hscStmt returns
        ------------- ------------------------------------
        let pat = expr ==> let pat = expr in return [coerce HVal x, coerce HVal y, ...]
                                        bindings: [x,y,...]

        pat <- expr ==> expr >>= \ pat -> return [coerce HVal x, coerce HVal y, ...]
                                        bindings: [x,y,...]

        expr (of IO type) ==> expr >>= \ it -> return [coerce HVal it]
          [NB: result not printed] bindings: [it]

        expr (of non-IO type, ==> let it = expr in print it >> return [coerce HVal it]
          result showable) bindings: [it]

        expr (of non-IO type,
          result not showable) ==> error

Bu yüzden GHCi komutunda bir komut üç adede kadar etki yapabilir: Bazı kodlar değerlendirilir, bazı şeyler yazdırılır ve bazı değişken adlar bağlanır. Durumunuz (yorumdaki ilk) değişkenleri bağlar, ancak yazdırmaz.

Sözdizimi do-notasyona benzemektedir, bu yüzden, sinan'ın cevabı biraz doğrudur, ama aslında kaputun altında olan şey değildir - aksi takdirde, hiçbir şey basılmazdı.


9
2017-12-27 11:51



Bu aşamada tüm bunları anlamadığımdan eminim, ancak GHCi'den öğrenmemesi gereken dereceyi görmek çok yararlıdır :-). Teşekkürler! - gwideman


GHCI komutları IO monad içinde yürütülür ve sözdizimi kuralları kullanır, bu yüzden desugaring kuralları geçerlidir. itibaren Gerçek Dünya Haskell

doNotation4 =
    do let val1 = expr1
           val2 = expr2
           {- ... etc. -}
           valN = exprN
       act1
       act2
       {- ... etc. -}
       actN

Çevirir:

translated4 =
    let val1 = expr1
        val2 = expr2
        {- ... etc. -}
        valN = exprN
    in do act1
          act2
          {- ... etc. -}
          actN

4
2017-12-27 09:20



Tamam, bu çok mantıklı. - gwideman