首页 > 解决方案 > 在 Reflex-DOM 中使用动态函数时的上下文/签名不匹配

问题描述

我能够编译这个下拉列表:

bodyElementPracticeType :: MonadWidget t m => m ()
bodyElementPracticeType = el "div" $ do
  el "h2" $ text "Dropdown"
  text "Select sport "
  dd <- dropdown Solo_Workout (constDyn (Map.fromList [(e, showSoloPersonPracticeType e) | e <- [minBound..]])) def
  el "p" $ return ()
  let selItem = result <$> value dd 
  dynText selItem 

result :: SoloPersonPracticeType -> T.Text
result e = fromJust $ Map.lookup e $ Map.fromList [(e, showSoloPersonPracticeType e) | e <- [minBound..]]

data SoloPersonPracticeType = 
        Solo_Workout 
    |   Solo_Run

showSoloPersonPracticeType :: SoloPersonPracticeType -> T.Text 
showSoloPersonPracticeType = \case 
    Solo_Workout -> T.pack "Workout"
    Solo_Run -> T.pack "Run"

deriving instance Enum SoloPersonPracticeType 
deriving instance Bounded SoloPersonPracticeType 
deriving instance Eq SoloPersonPracticeType 
deriving instance Ord SoloPersonPracticeType 

instance Universe SoloPersonPracticeType where 
    universe = [minBound..]

但是我在 Obelisk 的框架内工作,所以我尝试了一些修改以将小部件放入那里指定的结构中:

frontend :: Frontend (R FrontendRoute)
frontend = Frontend
  { _frontend_head = do
      el "title" $ text "The App Name"
      elAttr "link" ("href" =: static @"bulma.css" <> "type" =: "text/css" <> "rel" =: "stylesheet") blank
  , _frontend_body = subRoute_ $ \case 
        FrontendRoute_Main -> do
            -- bodyElementPracticeType :: MonadWidget t m => m ()
            let bodyElementPracticeType = el "div" $ do
                el "h2" $ text "Dropdown"
                text "Select sport "
                dd <- dropdown Solo_Workout (constDyn (Map.fromList [(e, showSoloPersonPracticeType e) | e <- [minBound..]])) def
                el "p" $ return ()
                let selItem = result <$> value dd 
                dynText selItem 

                -- result :: SoloPersonPracticeType -> T.Text
                let result e = fromJust $ Map.lookup e $ Map.fromList [(e, showSoloPersonPracticeType e) | e <- [minBound..]]
                       return ()
  }

但我收到此错误:

frontend/src/Frontend.hs:184:17-125: error:
    The last statement in a 'do' block must be an expression
      let result e
            = fromJust $ Map.lookup e
                $ Map.fromList
                    [(e, showSoloPersonPracticeType e) | e <- [minBound .. ]]
    |
184 |                 let result e = fromJust $ Map.lookup e $ Map.fromList [(e, showSoloPersonPracticeType e) 
| e <- [minBound..]]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

错误信息很清楚,但是:1.我不知道这是否是正确的方法和2.如果是正确的方法,我该如何将最后let result e = ...一位放入一个do块中?

或者,当我将函数移到result函数之外时frontend,会出现以下错误:

frontend/src/Frontend.hs:177:17-41: error:
    • Could not deduce (Monad m0) arising from a do statement
      from the context: ObeliskWidget js t (R FrontendRoute) m
        bound by a type expected by the context:
                   forall js t (m :: * -> *).
                   ObeliskWidget js t (R FrontendRoute) m =>
                   RoutedT t (R FrontendRoute) m ()
        at frontend/src/Frontend.hs:(61,12)-(230,3)
      or from: a ~ ()
        bound by a pattern with constructor:
                   FrontendRoute_Main :: FrontendRoute (),
                 in a case alternative
        at frontend/src/Frontend.hs:174:9-26
      The type variable ‘m0’ is ambiguous

标签: haskellreflexreflex-dom

解决方案


推荐阅读