记住这个反射计划:
{-# LANGUAGE ScopedTypeVariables, RecursiveDo #-} import Control.Applicative import Control.Monad import Control.Monad.IO.Class import Prelude hiding (div) import Reflex.Dom import qualified Data.Map as M clickMe :: MonadWidget t m => m (Event t ()) clickMe = do rec (e,_) <- elAttr' "button" M.empty (display c) c :: Dynamic t Int <- count (domEvent Click e) return $ domEvent Click e div :: forall t m a . MonadWidget t m => m a -> m a div = elAttr "div" ("style" =: "border : 1px solid black") app :: forall t m . MonadWidget t m => m () app = div $ do aClicks <- clickMe bClicks <- clickMe a <- count aClicks b <- count bClicks l <- combineDyn (\a b -> replicate (a-b) ()) a b simpleList l (const clickMe) return () main = mainWidget app
如果您从删除类型注释div
或者app
,该程序将无法与巨大的,可怕的错误类型编译.如果你删除它们,它将再次编译.从程序员的角度来看,当有人试图逐步注释未注释的程序时,这会给用户带来糟糕的体验.将未正确的类型注释添加到未注释的术语中会导致编译器错误,这会导致程序员认为他的类型错误.
这是通过删除div
注释获得的错误.
这些是推断类型.
为什么会这样?