我从 Haskell 开始,我需要帮助使用ReaderT
和StateT
Monads 将函数拼接在一起。
理想情况下,如果可能的话,所有函数都将具有相同的签名(我理解那些 Monad 应该提供帮助),并且能够读取环境并更改状态。
下面的代码应该openClientSocket
使用初始环境简单地打开一个 Socket ,在链中initialNetwork
注入socket
and ,然后调用作为参数传递的“下一个”函数(在这种情况下是函数)。address
func
sendMsg
但是我面临多个问题:
a)我应该如何调用传入
func
的openClientConnection
?b)
HNT
Monad 与其他 Monad 组成(?)。我如何阅读和操作内部 Monads ?
那么有人可以帮我修复这段代码,如果可能的话,派生/解释“理想”模式以实现主题中描述的目标。
非常感谢
湾。
import Control.Monad.Reader
import Control.Monad.State
import Network.Socket
import Network.Multicast
_MULTICAST_IP_ADDR_ :: HostName
_MULTICAST_IP_ADDR_ = "224.0.0.99"
_MULTICAST_PORT_ :: PortNumber
_MULTICAST_PORT_ = 9999
data NetworkEnv = NetworkEnv {
getMulticastIP :: HostName,
getMulticastPort :: PortNumber
} deriving (Show)
type NetworkEnvT = ReaderT NetworkEnv
data ClientSocket = ClientSocket {
getClientSocket :: Socket,
getAddress:: SockAddr
} deriving (Show)
type ClientSocketT = StateT ClientSocket
type HNT m = ClientSocketT (NetworkEnvT m)
initialNetwork :: NetworkEnv
initialNetwork = NetworkEnv { getMulticastIP = _MULTICAST_IP_ADDR_, getMulticastPort = _MULTICAST_PORT_ }
openClientConnection :: HNT m a -> m a
openClientConnection func = do
env <- ask
(sock, addr) <- liftIO $ multicastSender (getMulticastIP env) (getMulticastPort env)
put $ ClientSocket sock addr
func -- <== How do I call func (sendMsg) here ??
sendMsg :: String -> HNT IO ()
sendMsg msg = do
NetworkEnv ip port <- ask
ClientSocket sock addr <- get
_ <- liftIO $ sendTo sock msg addr
liftIO $ print "done"
doRun = runReaderT ( openClientConnection . (sendMsg "Hello") ) initialNetwork