Dart是否支持函数式编程?

时间:2013-05-25 05:41:00

标签: functional-programming dart

Google Dart语言是否允许进行函数式编程?特别是,是否支持以下功能?

  • 存储为变量(引用)的函数,
  • 功能性currying,
  • 懒惰参数

函数式编程的其他功能?

看起来Dart不支持不可变数据。

7 个答案:

答案 0 :(得分:21)

Dart具有一流的功能,并支持许多函数式编程结构。以下是将函数赋值给变量和curried函数的一些示例:

main() {
  f1(x) => x * 2;         // Define the function f1
  var f2 = f1;            // Assign f1 to the variable f2
  print(f2(7));           // Feel free to call f2 like any other function

  add(a) => (b) => a + b; // Curried addition
  print(add(3)(4));       // Calling curried addition

  var add3 = add(3);      // Combining the
  print(add3(2));         //  concepts
}

正如预期的那样,这会产生:

14
7
5

我不相信懒惰的参数是可能的,你已经注意到有明显可变的数据。

答案 1 :(得分:5)

取决于“函数式编程”的含义。函数是第一类对象,它涵盖了第1点,有Function.apply允许你自己实现currying,所以它涵盖了第2点,但除此之外,Dart不是很实用(不变性 - 不,参考透明度 - 不,懒惰的评价 - 不,你还有什么 - 可能也没有。)

答案 2 :(得分:4)

关于不变性的小例子:

class Point {
  Point(this.x, this.y);
  int x,y;
  int get sum => x + y;
}
class ImmutablePoint{
  final  int x,y, sum;
  const ImmutablePoint(x,y) :
    this.x = x,this.y = y,this.sum = x + y;
}

class SemiImmutablePoint {
  int _x, _y; // _ -like private but not access protected by the VM.
  SemiImmutablePoint(this._x, this._y);
  int get x => _x;
  int get y => _y;
}

void main() {
  List<int> li = [1,2,3,4,5];
  final List<int> immutableLi = const [1,2,3,4,5];
  li[1] = 10; //ok
  li = [6,7,8]; //ok
  immutableLi[1] = 10; //error because const
  immutableLi = [6,7,8]; //error because final
  var p = new Point(5,10);
  p.x = 10; //ok
  p.sum = 10; // error can't be directly mutated
  var p2 = const ImmutablePoint(5,10); // compile-time constant
  p2.x = 10; //error
}

您可以将FP与Dart一起使用,甚至可以使用没有类型或不变性的语言,如JS。它只是一种风格,它不需要用语言进行原生实现。

Scala FP范例之类的语言通常使用类型系统实现,因此它更具限制性,更难以无意中破坏。但与此同时,你需要从lib用户那里获得真正复杂类型系统的专业知识,有时甚至是类别理论 - 否则很难从知道这个东西是&#34; monad&#34;或&#34; monoid&#34;管他呢。我可以使用列表而不知道那些是monad或者是真正有用的概念&#34; future&#34;在达特。在没有&#34的情况下实施FP;键入magic&#34;它通常更清晰,更容易被普通开发人员掌握。但同时拥有强大的类型系统可以帮助编译器执行高级代码优化并实现更好的静态代码分析。

Category theory for JavaScript programmers - 值得关注。

已添加:现在收藏品已UnmodifiableListView UnmodifiableMapBase UnmodifiableMapView

答案 3 :(得分:3)

到最后一点,不变性,请参阅:

为不可变集合和“值类型”提供库和代码库支持。这些有助于弥合OO和函数式编程之间的差距,例如允许对不可变值进行内联“更新”:

var node = new Node((b) => b
  ..left.left.left.right.left.right.label = 'I’m a leaf!'
  ..left.left.right.right.label = 'I’m also a leaf!');
var updatedNode = node.rebuild((b) => b
  ..left.left.right.right.label = 'I’m not a leaf any more!'
  ..left.left.right.right.right.label = 'I’m the leaf now!');

其中“node”和“updatedNode”都是不可变的。本文中的更多详细信息:built_value for Immutable Object Models

答案 4 :(得分:3)

似乎有一种更流行的解决方案,称为dartz

DARTZ

  • 按照catsscalazthe standard Haskell libraries的精神键入类层次结构
  • 不可修改的持久性集合,包括IVector,IList,IMap,IHashMap,ISet和AVLTree
  • 用于以功能样式进行编程的Option,Either,State,Tuple,Free,Lens和其他工具
  • 评估,读者+作家+国家+个人+未来+瑞士军刀单子
  • 所包含类型以及几种标准Dart类型的类型类实例(Monoid,可遍历函子,Monad等)
  • 传送带,纯功能流的实现
  • Examples,展示了核心概念

我不知道如何使用它,但是有示例。

答案 5 :(得分:2)

进一步改善Dart FP体验的套装 https://github.com/vsavkin/fpdart

关于尾递归的一个悬而未决的问题 https://code.google.com/p/dart/issues/detail?id=29

答案 6 :(得分:1)

您可以将此软件包用于函数currying:https://pub.dev/packages/functional

它还可以提高代码的可读性。

  int add(int a,int b) => a+b;

现在该函数可以按以下方式进行处理。

  final inc = add % 1;
  final dec = add % -1;

  print(inc(5)); // Same as add(1, 5);
  print(dec(5)); // Same as add(-1, 5);