案例陈述未评估

时间:2012-02-18 21:43:58

标签: haskell

如果m2和m相等,我想进行IO操作(通过网络发送一些东西),不返回任何内容并更新我的地图。我已经精心设计了以下代码并且想知道(1)这是否可以重构为更少笨重的东西(2)为什么我的案例表达式应该发送消息不会被评估或至少没有消息被发送。

如果我取消注释底部的代码,那么事情就会按照我的意愿发送,但当然不管m2的值是什么就发送出来。

main = withSocketsDo $ do
     s <- socket AF_INET Datagram defaultProtocol
     (q, m) <- newRq
     let m2 = appendMsg "first" key m
         _ = case m2 of        
                   val | m2 == m -> do let Just messages = Map.lookup ("192.168.1.1", 4711) m in sendq s (B.pack $ unwords messages) "192.168.1.1" 4711
         (q4, m4) = case m2 of 
                   val | m2 == m -> deleteRec key q m2
                       | otherwise -> (q, m2)
     --let Just messages = Map.lookup ("192.168.1.1", 4711) m
     --sendq s (B.pack $ unwords messages) "192.168.1.1" 4711

我知道没有为m2和m不相等的所有情况定义_,但是sendq返回IO ()并且我想不出一些合理的东西可以添加到| otherwise ->这将返回同类型。

1 个答案:

答案 0 :(得分:4)

_ = case m2 of开头的两行代码完全没有!这是因为绑定值_永远不会被评估,因为它在其他任何地方都没有被使用(或者甚至被提及)。

我想要的是来自when的{​​{1}}函数。它的类型为Control.Monad;你可以按如下方式使用它:

Monad m => Bool -> m () -> m()

但您必须在 when (m == m2) (send the messages ...) 块之外使用它,即作为主let表达式的一部分。

还有一件事,你的代码:

do

可以简化为:

     (q4, m4) = case m2 of 
               val | m2 == m -> deleteRec key q m2
                   | otherwise -> (q, m2)