main = mainWidget $
  el "div" $ do
    let fileInputConfig = FileInputConfig (constDyn Map.empty)
    fi <- fileInput fileInputConfig

    let uploads   :: Dynamic t [File]            = value fi
    upload        :: Dynamic t (Maybe File)      <- (return . fmap headMay) uploads
    getNameAction :: Dynamic t (Maybe (IO Text)) <- (return . fmap (getNameText <$>)) upload
    filename      :: Dynamic t (Maybe Text)      <- (return . fmap (unsafePerformIO <$>)) getNameAction

    el "div" $ dynText (show <$> filename)
  return ()
  where getNameText :: MonadIO m => File -> m Text
        getNameText = getName

我尽了最大的努力来使用这些类型玩点对点游戏,但如果不使用unsafePerformIO,我就找不到出路。我认为在这种情况下是安全的,但是显然还有其他类似的事情可能不安全。

最佳答案

对于这样的事情,通常需要performEvent。我手边没有提供更多细节的编译器/ REPL,并且该函数某种程度上隐藏在某些类型类黑客(https://github.com/reflex-frp/reflex/blob/9575a5660334fb8a617da1cd9aa1b522e8e4ddb7/src/Reflex/PerformEvent/Class.hs)之后,但是要点是,如果您有一个携带IO的事件,则可以运行无论发生此事件的地方。

现在,您有了Dynamic,但是您可以

  • 从中提取事件
  • 也许不需要动态(它没有意义,因为您不想窥视IO的值)
  • 08-26 15:10