, bir tane olmadan aşağıdaki kodu yazdım. Standart girdi çizgisini satır satır okur ve boş bir çizgi karşılaşıncaya kadar her satırı tersine çevirir. Ayrıca State
kullanarak satırları sayar ve sonunda toplam sayısını görüntüler.Kullanım iki monads monad transformatörleri nasıl kullanılacağını anlamak için
import Control.Monad.State
main = print =<< fmap (`evalState` 0) go where
go :: IO (State Int Int)
go = do
l <- getLine
if null l
then return get
else do
putStrLn (reverse l)
-- another possibility: fmap (modify (+1) >>) go
rest <- go
return $ do
modify (+1)
rest
Her satırdan önce geçerli satır numarasını eklemek istedim. Ben StateT
ile yapmak başardı:
import Control.Monad.State
main = print =<< evalStateT go 0 where
go :: StateT Int IO Int
go = do
l <- lift getLine
if null l
then get
else do
n <- get
lift (putStrLn (show n ++ ' ' : reverse l))
modify (+1)
go
Sorum şu: nasıl monad transformatörleri olmadan sürümünde aynı şeyi?
Bunu farkettim. Benim verimliliğe aşkına bir monad trafosu olmayan versiyonu aramıyorum, sadece benziyor ve umarım monad transformatörleri ihtiyacının daha iyi takdir elde, iki karşılaştırarak şeyler öğrenmek olacağını görmek istiyorum. – ByteEater
Ayrıca, her satırda biriken devlet hesaplamasını çalışan ben kabul edilir ve tam da bu nedenle reddedildi taşıyor çünkü monads kullanmak doğru yolu görünmüyor, basit 'Int' daha iyi bir seçim olacaktır. Üstelik, artımlı olarak bir fark yaratmaz, fakat kavramsal olarak yanlış olur, çünkü 'State' hesaplaması' change (+1) 'eylemlerini hazırlayarak yapılır; '(+ uzunluk l)' değiştir, gerektiği gibi çalışmayacak. – ByteEater
@ByteEater, bunu bir monad trafosu olmadan yapmanın yolu, sadece "Int" (el sıkıcı) etrafından geçmek ya da bir "IORef" kullanmak (IO 'benzeri şeylerle sınırlı olmak ve potansiyel olarak verimsiz olmaktır) kutu kaçınılmaz veya güncellemeler nadirdir). Başka ne aradığını bilmiyorum. – dfeuer