2014-04-04 16 views
11

Netwire programlarına giriş alınıyor.Ben benim çıkışlara benim girdileri dönüştürmek isteyen tüm teller yazma sorunum yok Netwire sürümü 5.</p> <p>ile başlıyorum

Şimdi, gerçek dünyadaki girdilerime bağlanmak için IO sarmalayıcısını yazmaya başladım ve biraz kafam karıştı.

Wire s e m a bs parametresi için özel bir oturum türü oluşturmalı ve sensör değerlerimi buraya yerleştirmem gerekiyor mu?

  1. class (Monoid s, Real t) => HasTime t s | s -> t ait Monoid s bağlamında nesi var: Eğer öyleyse

    , bu soruları var? Ne için kullanılır?

  2. Sensör okumalarım ile bir Map String Double üzerinde çalışmayı düşünüyordum, ama benim teklem sözlükleri nasıl ezmeli? Sol eğilimli mi olmalı? Sağ önyargılı? Yukarıdakilerin hiçbiri?

Değilse, ne yapmam gerekiyor? Benim girişimi temsil eden formunun bazı s için tellerin sonuna gelmek istiyorum.

Ben (teller kendilerini saf olmamı sağlayan ve üst düzey tel arası adımları koduna IO hapsedilmesini, istemek veya bu amaçla Wire ait monadic m parametre kullanmak gerekmez benim anladığıma s). Bu yanlış mı?

+0

Benim örnekte, bu (sadece kopyalamayın, programın diğer kısımları farklıdır) yaptığı önyargılı. Ve aslında monadik bağlamı burada bir okuyucu monadını yapmanın ve burada sensör bilgilerinizi doldurmanın burada mantıklı olacağını düşünürdüm. Bu, kablolarınızı adım attığınız yeri gerçekten etkilemez, çünkü sadece 'runReader' (veya daha fazla şeyle uğraşmak isterseniz runReaderT ') çalıştırabilirsiniz. – Cubic

+0

Öğreticiler/örnekler, sensör verilerini almak için iç kablolardaki IO eylemlerini kullanmayı önerir. Örneğin. İçinde 'getKey' ile' mkGen_' kullanın. Sorunun genelleştirilmesiyle ilgilenecektim: “IO eylemlerinin tüm tellere giriş olarak tüm IO verilerinin beslenmesi ile karşılaştırıldığında, IO eylemlerinin tellerin içinde bulunmasının avantajları ve dezavantajları nelerdir?” – crosser

cevap

2

Wire s e m a b'a veri yerleştirmenin en kolay yolu, a giriş yolu ile yapılır. Veriler, s numaralı eyalet deltası veya Monad 'un dışındaki verileri almak için WPure veya WGen kullanımı yoluyla mümkündür, ancak bunlar ana soyutlamalardan uzaklaşır. Ana özetlemeler Arrow ve sadece a b hakkında bilgi sahibi olan ve s e m ile ilgili olmayan Category'dur.

a girdisi olarak girdi sağlayan çok basit bir program örneği. double, programın en dıştaki telidir. repl, kabloyu çalıştırmak için stepWire numaralı telefonu kullanan küçük bir okuma-değerlendirme-yazdırma döngüsüdür. Biz stepWire ile zaman geçmesi

import FRP.Netwire 
import Control.Wire.Core 

import Prelude hiding (id, (.)) 

double :: Arrow a => a [x] [x] 
double = arr (\xs -> xs ++ xs) 

repl :: Wire (Timed Int()) e IO String String -> IO() 
repl w = do 
    a <- getLine 
    (eb, w') <- stepWire w (Timed 1()) (Right a) 
    putStrLn . either (const "Inhibited") id $ eb 
    repl w' 

main = repl double 

Bildirim değil, toplam geçen zaman. Farklı bir üst düzey tel çalıştırarak bunun doğru bir şey olduğunu kontrol edebiliriz. Ben sadece Ok şekilde bu çözüldü

a 
1 
b 
2 
c 
3 
1

, bu nedenle bu daha composible olabilir: İstenen çıkışı

timeString :: (HasTime t s, Show t, Monad m) => Wire s e m a String 
timeString = arr show . time 

main = repl timeString 

. İsterseniz yayınlarımı okuyabilirsiniz. Kleisli Arrow in Netwire 5? ve Console interactivity in Netwire?., Sen kaldırabilir size terminalden karakterleri almak istiyorum varsayarak Sonra

mkKleisli :: (Monad m, Monoid e) => (a -> m b) -> Wire s e m a b 
mkKleisli f = mkGen_ $ \a -> liftM Right $ f a 

: ikinci gönderinin Kleisli fonksiyonları (Yani, şey a -> m b olan) kaldırılması için bu ihtiyaç

İlk komple interaktif programı var bunu yaparak hGetChar: (Ben sadece benim önceki yayınlardan rahatsız kodu soyulmuş) bu runWire fonksiyonunu test etmedim

inputWire :: Wire s() IO() Char 
inputWire = mkKleisli $ \_ -> hGetChar stdin 

, ama senin tellerini çalıştırmalısınız:

runWire :: (Monad m) => Session m s -> Wire s e m()() -> m() 
runWire s w = do 
    (ds, s') <- stepSession s 
    -- | You don't really care about the() returned 
    (_, w') <- stepWire w ds (Right()) 
    runWire s' w' 

Giriş telini, istediğiniz diğer Teller veya Oklar gibi istediğiniz yerde oluşturabilirsiniz.

mainWire = proc _ -> do 
    c <- inputWire -<() 
    q <- quitWire -< c 
    outputWire -< c 
    returnA -< q 

Veya, tek satırlık: kalan Harita için monoid örneği var

mainWire = inputWire >>> (quitWire &&& outputWire) >>> arr (\(q,_) -> q) 
İlgili konular