本文介绍了功能性香蕉旅行者 - 输入处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 这是我的 Traveler 项目的一个子问题。 我已经将处理输入的粗糙代码放在一起。它的工作原理,直到我介绍 TChan 混合。以下是工作代码,并举例说明如何使用它。然后,我会改变它并解释我为什么这样做。然后,我会讨论这个问题。 { - #LANGUAGE ScopedTypeVariables# - } import Control.Monad (永久)导入Control.Concurrent(forkIO)导入Control.Monad.STM(STM,原子地)导入Control.Concurrent.STM.TChan 导入Reactive.Banana import Reactive.Banana.Frameworks data Planet = Vulcan | Mars | Terra 导出(Eq,Read,Show) 数据命令=移动星球 |看看 |退出 |无派生显示 makeNetworkDescription :: AddHandler(也许命令) - > IO EventNetwork makeNetworkDescription addCommandEvent =编译$ do eInput< - fromAddHandler addCommandEvent let eCommand = filterJust eInput bCommand = stepper Null eCommand eCommandChanged< - changes bCommand reactimate $(\\\ - > appendFileoutput.txt(Command is++ show n))< $> eCommandChanged 执行 ghci ,Maybe Command - > IO()) networkDescr< - makeNetworkDescription addCommandEvent actuate networkDescr return(Just $ Look)>> = fireCommand 所以,现在我已经有了基本的机制,我想开始构建它。这将是一个多人游戏。解决这个问题的第一步就是从输入处理中获取来自 TChan 的输入。这个想法是,所有的玩家都会写这个 TChan ,每个命令都会按照它的顺序处理。 inputFrame :: TChan Command - > IO() inputFrame commandChannel = do (addCommandEvent,fireCommand)< - newAddHandler networkDescr< - makeNetworkDescription addCommandEvent 执行networkDescr forkIO $ forever tryReadTChan commandChannel)>> = fireCommand return() 在 ghci 中使用它。 commandChan< - atomically $ newTChan :: IO(TChan Command) _< - 原子地$ writeTChan commandChan Look output.txt 不会被写入。正在读取 commandChan ,因为我在填充它后检查它是否为空。这显然是我做错了吗?如果没有,我该如何解决这个问题呢?此外,对于我的预期目的, TChan 是正确的选择吗? 解决方案 fireCommand) 但我没有测试过这个。此外,在猜测,你可能会想在这里避免 tryReadTChan 。只需使用普通的 readTChan ,这样你就可以获得高效的重试而不是轮询。 This is a sub-problem from my Traveller project.I've put together the rudementary code that will handle input. It works, until I introduce a TChan to the mix. Below is the working code, with an example of how to use it. Then, I will change it and explain why I am doing so. Then, I'll talk about the problem.{-# LANGUAGE ScopedTypeVariables #-}import Control.Monad (forever)import Control.Concurrent (forkIO)import Control.Monad.STM (STM,atomically)import Control.Concurrent.STM.TChanimport Reactive.Bananaimport Reactive.Banana.Frameworksdata Planet = Vulcan | Mars | Terra deriving (Eq,Read,Show)data Command = Move Planet | Look | Quit | Null deriving ShowmakeNetworkDescription :: AddHandler (Maybe Command) -> IO EventNetworkmakeNetworkDescription addCommandEvent = compile $ do eInput <- fromAddHandler addCommandEvent let eCommand = filterJust eInput bCommand = stepper Null eCommand eCommandChanged <- changes bCommandreactimate $ (\n -> appendFile "output.txt" ("Command is " ++ show n)) <$>eCommandChangedExecuting the following in ghci will demonstrate that this works.(addCommandEvent,fireCommand) <- newAddHandler :: IO (AddHandler (Maybe Command),Maybe Command -> IO ())networkDescr <- makeNetworkDescription addCommandEventactuate networkDescrreturn (Just $ Look) >>= fireCommandSo, now I have have the basic mechanism in place, I want to start building it out. This is going to be a multiplayer game. The first step in addressing this as far the the input handling goes is getting input from a TChan. The idea being, all players will write to this TChan, and each command will be processed in the order it arrived.So I added a new function 'inputFrame'inputFrame :: TChan Command -> IO ()inputFrame commandChannel = do (addCommandEvent,fireCommand) <- newAddHandler networkDescr <- makeNetworkDescription addCommandEvent actuate networkDescr forkIO $ forever (atomically $ tryReadTChan commandChannel) >>= fireCommand return ()Here is how I attempt to use it, in ghci.commandChan <- atomically $ newTChan :: IO (TChan Command)_ <- atomically $ writeTChan commandChan Lookoutput.txt doesn't get written to. commandChan is being read, as I check to see if it becomes empty after populating it. Is it obvious what I'm doing wrong? If not, how may I go about troubleshooting the problem? Also, for my intended purposes, is a TChan the right choice? 解决方案 You probably wantedforkIO $ forever (atomically (tryReadTChan commandChannel) >>= fireCommand)but I haven't tested this. Also, at a guess, you probably will want to avoid tryReadTChan here. Just use plain old readTChan, so that you get the efficient retry instead of polling. 这篇关于功能性香蕉旅行者 - 输入处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
06-24 10:20