Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
函数式编程中的扩展技术,如F#_F#_Functional Programming - Fatal编程技术网

函数式编程中的扩展技术,如F#

函数式编程中的扩展技术,如F#,f#,functional-programming,F#,Functional Programming,在面向对象编程中,继承和虚拟方法是创建可扩展代码的常见场景。在更复杂的设置中,工厂方法(或依赖框架)有助于扩展基本代码 函数式编程(如F#)中创建可扩展代码的常用方法是什么?函数式编程中的基本扩展技术是 编写高阶函数(将其他函数作为参数的函数) (功能)多态性(使用类型参数化的函数和类型-在C#术语中,泛型类型和方法) 例如,您可能会将函数作为参数传递,而不是使用抽象方法(修改对象的某些状态)。该函数将采用所有必要的状态来进行计算(通过OO中的抽象方法完成),并将返回新状态(或任何计算结果)

在面向对象编程中,继承和虚拟方法是创建可扩展代码的常见场景。在更复杂的设置中,工厂方法(或依赖框架)有助于扩展基本代码


函数式编程(如F#)中创建可扩展代码的常用方法是什么?函数式编程中的基本扩展技术是

  • 编写高阶函数(将其他函数作为参数的函数)
  • (功能)多态性(使用类型参数化的函数和类型-在C#术语中,泛型类型和方法)
例如,您可能会将函数作为参数传递,而不是使用抽象方法(修改对象的某些状态)。该函数将采用所有必要的状态来进行计算(通过OO中的抽象方法完成),并将返回新状态(或任何计算结果)

通用(多态)代码,比如
list
,是扩展技术的另一个例子。您可以使用一些数据结构和函数(例如,
List.map
),您可以将其与以前未知的类型(列表项的类型)一起使用,并指定特定于此类型的行为(例如筛选谓词)。列表是一个非常基本的示例,但它也适用于非集合类型

在更复杂的设置中,编程语言之间存在更大的差异

  • 在Haskell中,人们可能使用类型类(有点像更强大的接口)
  • 在OCaml中,人们使用函子(类似于经典的函数多态性,但也可以通过多个函数和类型进行参数化)
  • 我认为,在F#中,人们通常将标准.NET技术(如接口)与基本函数技术(高阶函数、将函数作为参数传递给对象构造函数等)混合使用
FP和OO的混合是一个非常强大的组合,所以您可能不需要像依赖框架这样更复杂的东西。

这是一个非常好的问题

以下是从以下方面得出的答案:

函数范式(意味着使用高阶函数)只提供了一种扩展形式:高阶函数。这些允许您计算出“内部”函数。例如,经常使用相同的第一个和最后一个代码块显示的代码:

let f x =
  first x
  stuff1 x
  last x

let g x =
  first x
  stuff2 x
  last x
可分解为一般高阶函数,可从特定情况中重用:

let hof stuff x =
  first x
  stuff x
  last x

let f = hof stuff1 x

let g = hof stuff2 x
积极地应用这一点可以产生诸如解析器组合器之类的设计模式,这是一种使代码具有可扩展性的非常强大和轻量级的技术。但是,它不能使数据类型具有可扩展性

但真正的函数式编程语言几乎总是包含更时髦的语言功能,以帮助扩展性:

  • Common Lisp具有Common Lisp对象系统(CLOS)和宏系统
  • 标准ML具有参数多态性和高阶模块系统
  • OCaml添加了多态变量、对象、可选参数和Camlp4宏系统
  • Haskell具有参数多态性和类型类,模板Haskell添加了宏
  • Scala具有Java风格的OOP,并添加了一些特性
阅读Chris Okasaki的优秀专著《纯函数数据结构》,了解一些使用标准ML中的高阶模块和Haskell中的类型类的伟大示例。Jacques Garrigue阅读了关于如何利用语言特性来解决表达问题的描述。然而,这些解决方案在野外非常罕见,尤其是在没有它们的情况下(例如在F#中),你可以走很长的路

从历史上看,这种多样性的出现是因为大多数函数式编程语言都是研究项目,因此它们的存在是为了增加新的特性。因此,在今天的函数式编程语言中,我们现在有各种不同形式的可扩展性

F#是一种不同的野兽,因为它的设计要求与.NET的其他部分无缝互操作(采用.NET风格的OOP)和实用性。因此,F#使用参数多态性保留ML核心,并添加.NET的对象系统。因此,您可以从通用高阶函数和传统OOP提供的易于扩展性中获益,但不能从任何更深奥的功能(如高阶模块、类型类和宏)中获益


F#开创的扩展性的唯一形式是活动模式。这些允许您将通过模式匹配分解结构的代码与具体的数据表示分离。这是将代码与数据分离的一种重要方法,从而使其更具可重用性。

高阶函数还包括将函数作为结果返回的函数,特别是包含与工厂等效的功能设计模式(currying)。OCaml人员还使用对象、多态变量和可选参数以及高阶模块(函子)来生成可扩展代码。Haskell有视图模式,这与活动模式类似。视图模式是活动模式,但IIRC和Haskell从未获得过它们。菲尔·瓦德勒(Phil Wadler)就是在这种情况下提出的。那么@Jon,你对.NET OO完善F#的可扩展性满意吗?起初我持怀疑态度,认为我错过了OCaml的多态变体,但最近在F#中进行了更多的OO实验,我开始认为它毕竟相当不错。@Stephen:我对F#的可扩展性感到满意,因为它足够好,可以成为一个非常有用的工具,是的。但我确实怀念多态变体。事实上,我一直在编写解析器,不得不在F#或Haskell中编写、消除歧义并维护一个
类型assoc=Left | Non | Right
联合类型,现在我觉得与OCaml相比,Haskell很乏味。冈崎也让我错过了高阶模块