2013-04-14 9 views
25

Sadece Haskell'i öğrenmeye başladım, ancak döngülerin yokluğu şu anda sinir bozucu. Fonksiyonlar için döngüler yazmayı öğrendim. Bununla birlikte, benim sorunum, döngüleri tekrarlarken bazı sonuçlar çıkarmak istiyorum. Bu basit görevi gerçekleştirmek için debug kullanmam gerekiyor.basit Haskell döngü

Yani şimdi ben ana yapısında bir dize 10 kez yazdırmak nasıl bir örnek takdir sadece ederim.

Başka bir deyişle, bu 10 kat yapmak istiyorum:

main = do 
    putStrLn "a string" 

teşekkür ederiz. Bunun benim görevim için çok aydınlatıcı olacağını hissediyorum. o monads dayalı beri sadece dışarı başlıyoruz

+2

burada cevaplanması gereken asıl soru işlevsel bir dille "döngüleri" yapmak istediğinizde, çağırmayı bir kullanmasıdır. Tek sinir bozucu olan şey şuna bakarsanız: monad kurucusundan (bu durumda IO) dolayı türler değişmez. Bu nedenle, monadik bağları tamamen birbirine bağlayan bir özyinelemeye ihtiyaç duyarsınız. Başka bir deyişle, bu, sadece, Haskell'in IO'yu tedavi ettiği "özel" yolun üstesinden gelmek için hafif bir varyasyona sahip bir özendirmedir. –

+0

Hatta Haskell'e yeni başladım ama kazandığım küçük bilgileri paylaşmak istiyorum. Birisi bana Haskell'de döngüler yapmak istediğinizde ya yineleme ya da liste anlamalarını düşündüğümü söyledi. Buradaki sorunuzla alakalı değil, ancak listedeki tüm öğeleri eklemek istediğinizi varsayalım. Tabi ki tüm elemanlar üzerinde yinelemelisiniz. Özyineleme çalışacak ve liste kavramasını kullanacak. –

cevap

36

Böyle baskı "bir dizge" n kere (n işlevi parametresi olarak), tekrarlamalı bir fonksiyon tanımlama olabilir: bir fonksiyon tanımlama

printStringNTimes 0 = return() 
printStringNTimes n = 
do 
    putStrLn "a string" 
    printStringNTimes (n-1) 

main = printStringNTimes 10 

bir miktar daha genel bir yaklaşım olacaktır tüm ES eylem n defa tekrar:

repeatNTimes 0 _ = return() 
repeatNTimes n action = 
do 
    action 
    repeatNTimes (n-1) action 

main = repeatNTimes 10 (putStrLn "a string") 

yukarıdaki fonksiyon zaten adı replicateM_ altında Control.Monad bulunmaktadır.

26

Eh Haskell'ın IO biraz zordur. Bu Control.Monad

Bu beste ve monadic eylemlerin uygulanması için yararlı fonksiyonları çok sahip gelen bir bağdaştırıcının replicateM_ kullanıyor

main = replicateM_ 10 $ putStrLn "a string" 

:

Senin sorunun olsa basit bir çözümü vardır.

+13

Cevabınız için kendi yararı için ayrıntılı olarak incelemek gerekirse: Haskell 'for' ve' while' döngülerine sahiptir, ancak dil yerleşiklerinden ziyade kütüphane işlevleridir. Örneğin, 'for' döngüsünün karşılığı 'Control.Monad'dan forM_' birleştiricisi olur. Bu durumda, ancak, replicateM_' daha özlüdür. –

+0

Yani, Control.Monad'ı içe aktarmanız gerekiyor, değil mi? – vikingsteve

1

Ben de Haskell bir acemi değilim ve daha az zarif ve henüz pragmatik yararlı bir çözümümüz var.

main = do 
    putStr result 
    where 
     string = "a string" 
     result = concat [string ++ "\n" | i <- [1,2..10]] 

Yani burada biz bir liste tanımladık, bunların elemanları, yeni bir satır karakteri tarafından takip yazdırmak istediğiniz dizelerdir.