SORU
27 Temmuz 2012, Cuma


Nasıl Kontrol oynayacak.Monad.Haskell yazar?

Fonksiyonel programlama ve son zamanlarda Learn You a Haskell, öğrenme yeniyim ama this chapter ile gittiğimde programı ile aşağıda takıldım:

import Control.Monad.Writer  

logNumber :: Int -> Writer [String] Int  
logNumber x = Writer (x, ["Got number: "    show x])  

multWithLog :: Writer [String] Int  
multWithLog = do  
    a <- logNumber 3  
    b <- logNumber 5  
    return (a*b)

Bir bu satırları kurtardım .hs şikayet: hangi dosya ve ama onu almak için benim ghci içine başarısız oldu

more1.hs:4:15:
    Not in scope: data constructor `Writer'
    Perhaps you meant `WriterT' (imported from Control.Monad.Writer)
Failed, modules loaded: none.

Tarafından türünü inceledim "info" komutu:

Prelude Control.Monad.Writer> :info Writer
type Writer w = WriterT w Data.Functor.Identity.Identity
               -- Defined in `Control.Monad.Trans.Writer.Lazy'

Benim bakış açıma göre, bu "Yazar w ..."newtype gibi bir şey olması gerekiyordu veri kurucu yem ve Yazar hakkında kafam çok karışık.

Sürüm ile ilgili bir sorun olabilir sanırım ghci benim sürüm 7.4.1

CEVAP
27 Temmuz 2012, Cuma


Control.Monad.Writer veri vermez paketi Writer kurucu. Bu LYAH yazıldığı zaman farklıydı sanırım.

Bu MonadWriter kullanarak ghci içinde typeclass

Bunun yerine, yazarlar writer işlevini kullanarak oluşturun. Ghci oturumunda örneğin, yapabilirim

ghci> import Control.Monad.Writer
ghci> let logNumber x = writer (x, ["Got number: "    show x])

Şimdi logNumber yazarların oluşturduğu bir fonksiyonudur. Kendi türü için sorabilirim:

ghci> :t logNumber
logNumber :: (Show a, MonadWriter [String] m) => a -> m a

Olayla türü döndüren bir işlevi olmadığını söylüyorözellikleyazar, daha ziyade MonadWriter türü sınıf uygulayan bir şey. Şimdi kullanabilirsiniz:

ghci> let multWithLog = do { a <- logNumber 3; b <- logNumber 5; return (a*b) }
    :: Writer [String] Int

(Giriş aslında hepsi tek bir satırda girilen). Burada multWithLog tipi Writer [String] Int belirtilen ettim. Şimdi koşabilirim:

ghci> runWriter multWithLog
(15, ["Got number: 3","Got number: 5"])

Ve ara işlemlerini yapın.

Neden kod şöyle yazılır?

Neden MonadWriter türü sınıfı oluşturmak için rahatsız? Nedeni monad transformers ile yapacak. Seni doğru anladım, Writer uygulamak için en kolay yolu bir çift üstüne newtype bir kapsayıcı

newtype Writer w a = Writer { runWriter :: (a,w) }

Bunun için monad bir örneğini bildirmek ve işlev yazabilirsiniz

tell :: Monoid w => w -> Writer w ()

sadece girişini açar. Şimdi günlüğü yetenekleri, ama aynı zamanda başka bir şey yok olan bir monad istediğiniz varsayalım ki bir ortam da okuyabilirsiniz. Bu gibi uygulamak istiyorum

type RW r w a = ReaderT r (Writer w a)

Çünkü artık yazar içinde ReaderT monad transformer, isterseniz günlük çıkış yapamazsın kullanın tell w (çünkü bu sadece çalışır açılmamış yazarlar) ama senin için kullanın. lift $ tell w, "asansörler" tell fonksiyonu ile ReaderT çok kolay erişim iç yazar monad. Eğer iki kat istersen transformers (hata işleme eklemek istediğini söyle) sonra lift $ lift $ tell w kullanmak gerekir. Bu hızlı bir şekilde hantal alır.

Bunun yerine, bir tür alt sınıf herhangi bir monad transformer yapabiliriz yazar örnek bir yazar etrafında sarıcı kendisi. Örneğin,

instance (Monoid w, MonadWriter w m) => MonadWriter w (ReaderT r m)

w bir monoid ve m eğer MonadWriter w ReaderT r m MonadWriter w. Bu tell işlevi doğrudan açıkça monad transformer üzerinden kaldırılması ile uğraşmak zorunda kalmadan dönüştürülmüş monad üzerinde kullanabiliriz anlamına gelir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • efaustus9

    efaustus9

    16 HAZİRAN 2006
  • jedimasterkyle

    jedimasterky

    11 ŞUBAT 2006
  • Peter Sharp

    Peter Sharp

    11 ŞUBAT 2013