2015-06-21 48 views
0

當我使用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是effectful,但我不是很肯定getTagName

更新:

我明白什麼是純函數是,它不應該改變程序的狀態,也許DOM是一個不好的例子。

我問這個問題是因爲在大多數封裝了現有js庫的庫中,幾乎每個函數都是有效的,即使它感覺不對。所以也許我的實際問題是 - 這個效果是否代表這個包裝的js庫中的需要,還是僅僅爲了防止它在內部是有狀態的?

回答

0

如果一個函數沒有改變狀態,並且它在給定相同的參數時返回相同的值,那麼它不需要返回Eff,否則它就會返回。

n.tagName是隻讀的,據我所知,它永遠不會改變。因此,getTagName是純粹的,可以不返回Eff

另一方面,getTextContent函數必須返回Eff。它不會改變狀態,但它在不同的時間會返回不同的值。

廣闊廣闊廣闊大多數JS的API(包括DOM)是effectful。getTagName非常少數例外之一。因此,在編寫FFI時,PureScript作者只是假設所有JS函數都會返回Eff,即使在他們不需要的罕見情況下也是如此。

值得慶幸的是最新的purescript-dom版本使用非Eff功能nodeNametagNamelocalName

0

Effectful函數是不pure功能,維基百科:

在計算機程序中,函數可被描述爲一個純函數,如果這兩個關於功能保持語句:

  1. 函數總是在給定相同參數值的情況下評估相同的結果值。函數結果值不能取決於任何隱藏信息或狀態,這些信息或狀態可能隨着程序執行的進行或程序的不同執行而改變,也不取決於來自I/O設備的任何外部輸入[...]。

  2. 對結果的評估不會導致任何語義上可觀察的副作用或輸出,例如可變對象的變異或輸出到I/O設備[...]。

由於DOM存儲狀態,功能包裝到DOM電話幾乎都是effectful。

有關PureScript的更多詳細信息,請參閱Handling Native Effects with the Eff Monad

+0

謝謝您的回答,我已經更新了我的問題,使之更加具體 – starper

+0

@starper是你需要將所有不純的函數註釋爲有效的,因爲編譯器/運行時必須以不同的方式對待它們(例如,它不能緩存函數調用的結果,因爲您可以使用純函數/ [引用透明表達式](https:// en.wikipedia.org/wiki/Referential_transparency_(computer_science))) – mb21

相關問題