我目前正在ghcjs中试验JSaddle库。
我还没有太多关于镜片的经验。在这个库的某个地方,他们似乎定义了一个吸气镜头,实际上是一种monadic二传手:
-- | Makes a setter for a particular property name.
--
-- > jss name = to (<#name)
--
-- >>> testJSaddle $ eval "'Hello World'.length = 12"
-- 12
-- >>> testJSaddle $ val "Hello World" ^. jss "length" 12
-- undefined
jss :: (ToJSString name, ToJSVal val)
=> name -- ^ Name of the property to find
-> val
-> forall o . MakeObject o => IndexPreservingGetter o (JSM ())
jss name val = to (\o -> o <# name $ val)
以下列方式使用它来设置新javascript对象的属性:
makeConfig :: JSM Object
makeConfig = do
object <- obj
object ^. jss "foo" 5
object ^. jss "bar" 7
return object
但是我想放下这个东西,并且有这样的东西:
makeConfig :: JSM Object
makeConfig = obj ^. jss "foo" 5
^. jss "bar" 7
我知道您可以在lens
库中执行此操作,因为setter实际上会返回更新的对象:
obj & _1 .~ 45
& _2 .~ 49
现在我做了一个小的shim函数,每次都返回输入值:
(~.) :: MakeObject o => o -> IndexPreservingGetter o (JS.JSM ()) -> JS.JSM o
a ~. b = a ^. b >> return a
这允许我按照我想要的方式使用jss
:
makeConfig :: JSM Object
makeConfig = obj ~. jss "foo" 5
~. jss "bar" 7
但我无法帮助,但我觉得我正试图解决已解决的问题。有没有更好的方式我不知道?
[编辑]
我确实尝试过这样的事情:
props :: MakeObject o => o -> [IndexPreservingGetter o (JS.JSM ())] -> JS.JSM o
props object p = mapM_ (object ^.) p >> return object
然后GHCJS抱怨不可预测的多态性......