Haskell 在反射dom中,如何将值从动态传递到外部javascript函数(FFI)
我对Haskell和dom还不熟悉,但我很喜欢这门语言。我一直在学习,这对我很有帮助 我目前正在尝试创建一个函数,该函数接受动态,并创建一个元素,每次动态中的值更改时都调用FFI函数。这是我试图做的一个简化版本Haskell 在反射dom中,如何将值从动态传递到外部javascript函数(FFI),haskell,ffi,reflex,Haskell,Ffi,Reflex,我对Haskell和dom还不熟悉,但我很喜欢这门语言。我一直在学习,这对我很有帮助 我目前正在尝试创建一个函数,该函数接受动态,并创建一个元素,每次动态中的值更改时都调用FFI函数。这是我试图做的一个简化版本 {-# LANGUAGE OverloadedStrings #-} import Data.Text as T import qualified GHCJS.DOM.Types as GDT import GHCJS.Types import Reflex.Dom foreign i
{-# LANGUAGE OverloadedStrings #-}
import Data.Text as T
import qualified GHCJS.DOM.Types as GDT
import GHCJS.Types
import Reflex.Dom
foreign import javascript safe
"$1.value = $2"
testSet :: JSVal -> JSVal -> IO()
testTB :: DomBuilder t m => Dynamic t T.Text -> m ()
testTB dt = do
(e, _) <- elAttr' "input" ("type" =: "text") blank
bob <- (testSet (GDT.pToJSVal e) . GDT.pToJSVal) <$> dt
return ()
main = mainWidget $ testTB $ constDyn "Hello World!"
{-#语言重载字符串}
导入数据。文本为T
将符合条件的GHCJS.DOM.Types导入为GDT
导入GHCJS。类型
导入反射.Dom
国外进口javascript安全
“$1.value=$2”
testSet::JSVal->JSVal->IO()
testTB::DomBuilder t m=>动态t.Text->m()
testTB dt=do
(e,∗)*)。
DOMTM=>
动态t文本->m()
在反射画布上。hs:11:11
预期类型:m(IO())
实际类型:动态t(IO())
•在“do”块的stmt中:
bob函数performEvent\uu
将强制执行javascript函数,但performEvent\u
需要事件t(WidgetHost m())
,并且,正如错误消息所指出的,您得到了动态t(IO())
您可以使用updated
将您的Dynamic t(IO())
转换为Event t(IO())
,并且可以使用fmap liftIO
将事件中的IO()
更改为WidgetHost m()
留下事件t(WidgetHost m())
您可以将其传递到performEvent\u
这是经过这些修改的代码。我删除了testSet
的第一个参数和testTB
中的元素创建,因为它们与问题/解决方案无关。我还添加了一些额外的类型声明。这些不是必需的,但可能会使事情更清楚
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Text as T (Text)
import qualified GHCJS.DOM.Types as GDT (pToJSVal)
import GHCJS.Types (JSVal)
import Reflex.Dom
import Control.Monad.Trans (liftIO)
foreign import javascript safe
"console.log $1"
testSet :: JSVal -> IO()
testTB :: forall t m. MonadWidget t m => Dynamic t T.Text -> m ()
testTB dt = do
let bob :: Dynamic t (IO ())
bob = (testSet.(GDT.pToJSVal)) <$> dt
bobIOEvent :: Event t (IO ())
bobIOEvent = updated bob
bobWidgetHostEvent :: Event t (WidgetHost m ())
bobWidgetHostEvent = fmap liftIO bobIOEvent
performEvent_ bobWidgetHostEvent
main = mainWidget $ do
ti <- textInput def
let dt = value ti
testTB dt
{-#语言重载字符串}
{-#语言范围类型变量#-}
导入数据。文本作为T(文本)
将符合条件的GHCJS.DOM.Types导入为GDT(pToJSVal)
导入GHCJS.Types(JSVal)
导入反射.Dom
进口控制单体转运(liftIO)
国外进口javascript安全
“console.log$1”
testSet::JSVal->IO()
testTB::对于所有t m。MonadWidget t m=>动态t.Text->m()
testTB dt=do
让bob::动态t(IO())
bob=(testSet.(GDT.pToJSVal))dt
bobIOEvent::事件t(IO())
bobIOEvent=已更新的bob
bobWidgetHostEvent::事件t(WidgetHost m())
bobWidgetHostEvent=fmap liftIO bobIOEvent
performEvent_ubWidgetHostEvent
main=mainWidget$do
i你试过liftIO
ing吗?我的意思是liftIO(testSet(GDTpToJSVal e).GDT.pToJSVal)=您选择省略大部分错误,这通常是非常全面的信息。了解错误可能会告诉您如何修复它;一个好的答案会给出修正并解释错误(教人钓鱼等等)。@epsilonhalbe刚刚尝试了liftM和liftIO的一些变体,但似乎无法使其工作。@user2407038刚刚添加了完整的错误消息。您无法从动态monad中获取t.Text值并将其直接用作testSet函数的参数。您必须在monad中以应用程序模式运行testSet函数。类似于testSet ptrToHTMLControl ptrToText
。
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Text as T (Text)
import qualified GHCJS.DOM.Types as GDT (pToJSVal)
import GHCJS.Types (JSVal)
import Reflex.Dom
import Control.Monad.Trans (liftIO)
foreign import javascript safe
"console.log $1"
testSet :: JSVal -> IO()
testTB :: forall t m. MonadWidget t m => Dynamic t T.Text -> m ()
testTB dt = do
let bob :: Dynamic t (IO ())
bob = (testSet.(GDT.pToJSVal)) <$> dt
bobIOEvent :: Event t (IO ())
bobIOEvent = updated bob
bobWidgetHostEvent :: Event t (WidgetHost m ())
bobWidgetHostEvent = fmap liftIO bobIOEvent
performEvent_ bobWidgetHostEvent
main = mainWidget $ do
ti <- textInput def
let dt = value ti
testTB dt