对每个操作采用原始输入的一元动作进行排序

时间:2018-01-16 17:27:55

标签: haskell monads lens lenses ghcjs

我目前正在ghcjs中试验JSaddle库。

我还没有太多关于镜片的经验。在这个库的某个地方,他们似乎定义了一个吸气镜头,实际上是一种monadic二传手:

https://github.com/ghcjs/jsaddle/blob/3f8b32833917f1a2dfbdb81ef00992fb54733c9a/jsaddle/src/Language/Javascript/JSaddle/Object.hs#L201

-- | 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抱怨不可预测的多态性......

0 个答案:

没有答案