【问题标题】:In functional programming, can a function call another function that was declared outside of it's scope and not passed as a parameter?在函数式编程中,一个函数可以调用另一个在其范围之外声明且未作为参数传递的函数吗?
【发布时间】:2015-10-31 04:37:26
【问题描述】:

使用在函数范围之外声明的函数是否违反了函数原则,例如不变性?还是专门指数组、字符串等数据。

例如:

var data ["cat", "dog", "bird"];

function doThing (val) { 
     return val + ", go away!" 
}

function alterData (data) {
    return data.map(doThing);
}

alterData(data);

上面的代码可以接受吗?还是需要将“doThing”函数作为参数传递给 alterData 函数?

我感到困惑的原因是,在函数式编程示例中,我经常看到使用语言的原生函数,而没有首先传递给函数。但是,这些示例从来都不够复杂,无法展示如何使用函数库。

问候

【问题讨论】:

  • 我删除了“不变性”标签,因为它完全无关紧要。
  • 你是对的,不是一个好标签。

标签: functional-programming


【解决方案1】:

在这方面,函数式编程与过程式编程没有什么不同——您编写的定义可以在它们范围内的任何地方重用。您可以通过各种机制控制范围内的内容,例如模块定义、模块导出列表和模块导入。例如(在 Haskell 中):

module My.Module
  -- List of definitions exported from this module 
  ( doThing
  , alterData
  ) where

-- Any definitions exported from `My.Other.Module` will be in scope 
-- in this one
import My.Other.Module

-- Can't name this `data` because it's a reserved word in Haskell
yourData :: [String]
yourData = ["cat", "dog", "bird"]

doThing :: String -> String
doThing val = val ++ ", go away!" 

alterData :: [String] -> [String]
alterData strings = map doThings strings

【讨论】:

    【解决方案2】:

    TL;DR

    在 FP 代码中依赖作用域很好。


    不变性意味着由名称表示的事物不能改变其值。不过,我不会将其称为函数式编程的“原则”。

    无论如何,这根本与范围无关。如果您想将一个函数参数化而不是另一个函数,则将事物作为参数传递是有意义的——本质上是使其成为 高阶函数。一个很好的例子是fold(也称为reduce) - 但map 也是一个。

    不过,在您的情况下,alterData 函数并没有增加太多价值。 mapping something over something 很常见,通常最好只提供一个元素函数,因为它从根本上更易于重用。

    如果您已将doThing 传递给alterData,您将使该功能基本上无用;如果我可以简单地使用map,我为什么要使用它?但是,将操作与映射打包在一起有时可能是一种有用的抽象。

    【讨论】:

      【解决方案3】:

      doThing 是这样的。 你需要这样做:

      var data = ["cat", "dog", "bird"];
      
      var doThing = function (val) { 
           return val + ", go away!" 
      }
      
      function alterData (data) {
          return data.map(doThing);
      }
      
      alterData(data);
      

      【讨论】:

      • 假设 alterData 函数是一个纯函数,它依赖于 doThings 函数来具有可预测的行为。如果doThings 函数更改其功能或被删除怎么办?然后alterData 的行为发生了变化,这意味着它不是纯粹的。所以在 FP 中我们不应该依赖作用域函数,我们应该传递函数使用的任何参数。
      猜你喜欢
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多