功能应该什么时候生效?

When function should be effectful?

当我使用 FFI 包装一些 API(例如 DOM API)时,是否有任何经验法则可以帮助我决定功能是否应该有效?

这是一个例子:

foreign import querySelectorImpl """
    function querySelectorImpl (Nothing) {
      return function (Just) {
        return function (selector) {
          return function (src) {
            return function () {
              var result = src.querySelector(selector);
              return result ? Just(result) : Nothing;
            };
          };
        };
      };
    }
  """ :: forall a e. Maybe a -> (a -> Maybe a) -> String -> Node -> Eff (dom :: DOM | e) (Maybe Node)

querySelector :: forall e. String -> Node -> Eff (dom :: DOM | e) (Maybe Node)
querySelector = querySelectorImpl Nothing Just

foreign import getTagName """
    function getTagName (n) {
      return function () {
        return n.tagName;
      };
    }
  """ :: forall e. Node -> Eff (dom :: DOM | e) String

感觉querySelector有效,但我不太确定getTagName

更新:

我明白什么是纯函数,它不应该改变程序的状态,也许 DOM 是一个不好的例子。

我问这个问题是因为在大多数包装现有 js 库的库中,几乎每个函数都是有效的,即使它感觉不对。所以也许我的实际问题是 - 这种效果是否代表这个包装的 js 库中的需要,或者它是否存在以防万一它在内部是有状态的?

有效函数是不是pure的函数,来自维基百科:

In computer programming, a function may be described as a pure function if both these statements about the function hold:

  1. The function always evaluates the same result value given the same argument value(s). The function result value cannot depend on any hidden information or state that may change as program execution proceeds or between different executions of the program, nor can it depend on any external input from I/O devices [...].

  2. Evaluation of the result does not cause any semantically observable side effect or output, such as mutation of mutable objects or output to I/O devices [...].

由于 DOM 存储状态,因此包装调用 DOM 的函数几乎总是有效的。

有关 PureScript 的更多详细信息,请参阅 Handling Native Effects with the Eff Monad

如果一个函数不改变状态,并且它总是(过去、现在和未来)return在给定相同的参数时具有相同的值,那么它不需要 return Eff,否则它会。

n.tagName 是只读的,据我所知,它永远不会改变。所以,getTagName是纯粹的,没有returnEff.

也可以

另一方面,getTextContent函数必须returnEff。它不会改变状态,但会在不同时间 return 不同的值。

绝大多数vastvast大多数JS API(包括DOM) 是有效的。 getTagName非常 少数例外之一。因此,在编写 FFI 时,PureScript 作者只是假设所有 JS 函数 return Eff,即使在他们不需要的极少数情况下也是如此。

谢天谢地 purescript-dom uses non-Eff functions for nodeName, tagName, localName 的最新版本,等等