0

代码可以编译,但运行时会陷入无限递归循环。循环进入的位置并不明显,尤其是在使用递归 do 或 monadfix 时。尝试在浏览器中调试时,它在 rts.js 行 6086 处的 fixIO 中找到循环评估

{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE RecursiveDo         #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MonoLocalBinds      #-}

import Reflex.Dom
import qualified Data.Text as T

main :: IO ()
main = mainWidget game

game :: MonadWidget t m => m ()
game = elClass "div" "game" $ do
  elClass "div" "game-board" $ do
    rec
      stateEv <- board stateEv [["","",""],["","",""],["","",""]]
    elClass "div" "game-info" $ do
      elClass "div" "statu" $ blank
      elClass "ol" "todo" $ blank

board :: MonadWidget t m
      => [[Event t T.Text]]
      -> [[T.Text]]
      -> m [[(Event t T.Text)]]
board s iss = elClass "div" "board" $ do
  el "div" $ do
    elClass "div" "status" $ text "Next player: X"
    mapM (boardRow s) iss

boardRow :: MonadWidget t m
         => [[Event t T.Text]]
         -> [T.Text]
         -> m [(Event t T.Text)]
boardRow s is = elClass "div" "board-row" $ mapM (square s) is

square :: (
            PostBuild t m
          , DomBuilder t m
          , MonadHold t m
          )
       => [[Event t T.Text]]
       -> T.Text
       -> m (Event t T.Text)
square stateEv i = do
  rec
    let ev = domEvent Click e
        ev' = updated dyn
        ev'' = tagPromptlyDyn dyn ev
        dyn = tooglePlayer <$> dynBool

    dyns <- mapM (holdDyn i) (concat stateEv)
    dynBool <- toggle True $ updated $ distributeListOverDyn dyns

    (e, _) <- elAttr' "button" ("type" =: "button" <> "class" =: "square") $ dynText dyn
  return ev''

tooglePlayer :: Bool -> T.Text
tooglePlayer True  = "X"
tooglePlayer False = "O"
4

0 回答 0