Üniversite için bir ödev yazma sürecinde, yeni Haskell monad'larını öğrenmenin her zaman zevkli eğlencesini yaşıyorum. Yuppi!!!Haskell State Monad'ın dağıtılması
ben gayet typechecks bir işlevi vardır:
compile :: Prog -> State VarsState String
compile [email protected](Prog functions) = do
s1 <- sequence (map (translate_func 0) [get_function prog name | name <- [func_name func | func <- functions]])
return $ trace ("here's the program: \n" ++ show prog) $ concat $ s1
ama bu başka fonksiyon zaman:
maybe_compile_prog ::
MaybeOK Prog -> String -> IO()
maybe_compile_prog (Error msg) _ = do
putStrLn ("error: " ++ msg)
maybe_compile_prog (OK prog) modulename = do
s1 <- compile prog
writeFile (modulename ++ ".m") ((header modulename) ++ s1)
çalışır adlandırmak, bu hat
s1 <- compile prog
kadar darbeler
, gerçek tip "State VarsState String" ile beklenen tür "IO t0" ile eşleşemediğini söyler.
Bunun sebebi, belki de ben_compile_prog IO() tipini döndürdüğünden, IO bilgilerini yalnızca açmayı umduğundan varsayıyorum. VarsState, State monad/
ile birlikte kullandığım özel bir veri türüdür. Ancak, sorun buysa ve varsayalım, bu basit dizgiyi belki_compile_prog dosyasına nasıl aktaracağımı bilmiyorum. Gerçekten, tüm yapmak istediğim şey budur - belki de belki de bir_ilgile.
Belki de bu devlet monadını açmak için düzgün bir yol var mı? Belki de “derleme” yi yeniden yazabilir, böylece çalışır durumdayken bazı durum bilgisi bilgisini alır, ancak daha sonra sadece bir dize döndürür (herhangi bir monoya sarılmaz)?
Herhangi bir bilgi eksikse lütfen bana bildirin.
Mükemmel dostum. Küçük bir şey hariç, "let s1 = evalState (derleme prog) initialState" ile derleme, "let s1 = evalState $ derleme prog initialState". Bir başka soru - diğer monadlar için böyle işler var mı? yani monad'ı açıp sadece sonucu döndüren işlevler? – nebffa
@nebffa tamamen söz konusu monoya bağlıdır, ancak evet, bazıları.Bütün monadlar için genel olarak yapabileceğiniz bir şey değil. Bir başka örnek de, “IO” monadının korkusuz “güvensizPerformi” olması olurdu, ama bunu kullanmamalısınız. –
Ah, evet, parantezleri karıştırın (önce durumu unuttun, ve eklerken '$' yi değiştirmeyi unutmayın). Head-up için teşekkürler. Birçok monad için, karşılık gelen fonksiyonlar vardır, ancak hepsi için değil. 'IO', hiçbirinin olmadığı bir yerdi [iyi, 'güvenli olmayan' ile başlayan bir isim var ve gerçekten gerçekten anlam ifade ediyor]. "RunIdentity", "runReader", "runWriter", "runCont", ... vardır. Bu işlevlerin bulunup bulunmadığı her bir monad için belgelere bakın. –