Tha*_*les 5 haskell ffi reflex
我是Haskell和反射的新手,但真的很喜欢这种语言.我一直在使用https://github.com/hansroland/reflex-dom-inbits/blob/master/tutorial.md来学习,这非常有帮助.
我目前正在尝试创建一个函数,它接受动态并创建一个元素,并在每次动态值发生变化时调用FFI函数.这是我正在尝试做的简化版本.
{-# 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!"
Run Code Online (Sandbox Code Playgroud)
这导致编译时错误:
reflex-canvas.hs:14:10: error:
• Couldn't match type ‘m’ with ‘Dynamic t’
‘m’ is a rigid type variable bound by
the type signature for:
testTB :: forall t (m :: * -> *).
DomBuilder t m =>
Dynamic t Text -> m ()
at reflex-canvas.hs:11:11
Expected type: m (IO ())
Actual type: Dynamic t (IO ())
• In a stmt of a 'do' block:
bob <- (testSet (GDT.pToJSVal e) . GDT.pToJSVal) <$> dt
In the expression:
do { (e, _) <- elAttr' "input" ("type" =: "text") blank;
bob <- (testSet (GDT.pToJSVal e) . GDT.pToJSVal) <$> dt;
return () }
In an equation for ‘testTB’:
testTB dt
= do { (e, _) <- elAttr' "input" ("type" =: "text") blank;
bob <- (testSet (GDT.pToJSVal e) . GDT.pToJSVal) <$> dt;
return () }
• Relevant bindings include
e :: Element EventResult (DomBuilderSpace m) t
(bound at reflex-canvas.hs:13:4)
dt :: Dynamic t Text (bound at reflex-canvas.hs:12:8)
testTB :: Dynamic t Text -> m () (bound at reflex-canvas.hs:12:1)
Run Code Online (Sandbox Code Playgroud)
我已经尝试了各种方法将Dynamic转换为am(),但无法弄明白.这样做的最佳做法是什么?
该函数performEvent_将强制执行一个 javascript 函数,但performEvent_需要一个Event t (WidgetHost m ())并且,正如错误消息指出的那样,你已经得到了一个Dynamic t (IO ()).
您可以使用updated将 your 转换Dynamic t (IO ())为 an Event t (IO ()),也可以使用将thefmap liftIO更改为 a留下您可以传递给IO ()EventWidgetHost m ()Event t (WidgetHost m ())performEvent_
这是经过这些修改的代码。我删除了第一个参数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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
229 次 |
| 最近记录: |