SORU
16 HAZİRAN 2012, CUMARTESİ


Devlet bir monad ile evleniyor

Üzerinde çalışıyorum bir Haskell proje içerir bağlayan bir büyük düğüm: ben bir ayrıştırma seri temsili bir grafik, her düğüm bazı ofset dosyayı ve başvuru başka bir düğüm tarafından ofset. Kendimi geri besleme sağlayan ayrıştırma sırasında bezlerine uzaklıklar bir harita oluşturmak için do rec blok ihtiyacım var.

Çalışma var bu, ve biraz-biraz-oldukça StateT-vari bir monad transformer içine çekilen:

{-# LANGUAGE DoRec, GeneralizedNewtypeDeriving #-}

import qualified Control.Monad.State as S

data Knot s = Knot { past :: s, future :: s }

newtype RecStateT s m a = RecStateT (S.StateT (Knot s) m a) deriving
  ( Alternative
  , Applicative
  , Functor
  , Monad
  , MonadCont
  , MonadError e
  , MonadFix
  , MonadIO
  , MonadPlus
  , MonadReader r
  , MonadTrans
  , MonadWriter w )

runRecStateT :: RecStateT s m a -> Knot s -> m (a, Knot s)
runRecStateT (RecStateT st) = S.runStateT st

tie :: MonadFix m => RecStateT s m a -> s -> m (a, s)
tie m s = do
  rec (a, Knot s' _) <- runRecStateT m (Knot s s')
  return (a, s')

get :: Monad m => RecStateT s m (Knot s)
get = RecStateT S.get

put :: Monad m => s -> RecStateT s m ()
put s = RecStateT $ S.modify $ \ ~(Knot _ s') -> Knot s s'

tie işlevi sihrin gerçekleştiği yer: 7* *Ara bir değer ve ben de kendi geleceği olarak besleyen bir devlet üretir. get geçmişin ve geleceğin Birleşik Devletleri hem de okuyabilir, ama put sadece "mevcut." değiştirmek için izin verdiğini unutmayın

Soru 1Bu uygulamak için iyi bir yol gibi düğüm-ipe genel olarak desen görünüyor mu? Ya da daha iyisi, birileri buna genel bir çözüm hayata geçirdi, Hackage karıştıran zaman gözden kaçırmışım? Muhtemelen daha şık göründüğü için bir süre Cont monad karşı başımı yendi, (Dan Burton similar post), ama beceremedim.

Tamamen öznel bir Soru 2: Tamamen arama kodunu arayan bulur yolu ile mutlu değilim:

do
  Knot past future <- get
  let {- ... -} = past
      {- ... -} = future
      node = {- ... -}
  put $ {- ... -}
  return node

Uygulama ayrıntıları besbelli ki, burada önemli nokta past future devlet almam sahip olmak,-maç desen onları ihmaliçinde bir bağlama yapalım(ya da açıkça önceki desen tembel olun) önemsiyorum ne olursa olsun özü, benim düğüm oluşturmak için, bu devlete, güncelleme ve nihayet düğümü döndürür. Gereksiz yere ayrıntılı görünüyor, ve ben özellikle ne kadar kolay yanlışlıkla past future devletler sıkı ayıklayan desen yapmak için sevmemek. Kimse daha iyi bir arayüz olabilirmi?

CEVAP
18 HAZİRAN 2012, PAZARTESİ


Uygulanması ile ilgili olarak, Okuyucu bir monad (gelecek için) bir kompozisyon ve Devlet bir monad (geçmiş) hediye edeyim. Sebebi senin geleceğin sadece bir kez (tie) ayarlayın ve sonra bir değişiklik yok.

{-# LANGUAGE DoRec, GeneralizedNewtypeDeriving #-}

import Control.Monad.State
import Control.Monad.Reader
import Control.Applicative

newtype RecStateT s m a = RecStateT (StateT s (ReaderT s m) a) deriving
  ( Alternative
  , Applicative
  , Functor
  , Monad
  , MonadPlus
  )

tie :: MonadFix m => RecStateT s m a -> s -> m (a, s)
tie (RecStateT m) s = do
  rec (a, s') <- flip runReaderT s' $ flip runStateT s m
  return (a, s')

getPast :: Monad m => RecStateT s m s
getPast = RecStateT get

getFuture :: Monad m => RecStateT s m s
getFuture = RecStateT ask

putPresent :: Monad m => s -> RecStateT s m ()
putPresent = RecStateT . put

İkinci sorunuza gelince, sizin veri akışı bilmek (yani senin için küçük bir kod örneği var) yardımcı olur. Sıkı desenleri her zaman döngüler neden olduğu doğru değil. Üretmeyen bir döngü oluşturmak için dikkatli olmak gerekir bu doğru ama tam olarak ne kısıtlamalar ve bina konum nasıl bağlıdır.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • 3dmmfavs

    3dmmfavs

    29 Kasım 2009
  • colacas

    colacas

    29 EKİM 2006
  • vgeller1

    vgeller1

    22 Kasım 2009