scala 函数式编程的非数值用例?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/381685/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Non-numerical use cases for functional programming?
提问by krosenvold
I just finished reading a book on scala. What strikes me is that every single example in the whole book was numerical in some form or another.
我刚读完一本关于 Scala 的书。让我印象深刻的是,整本书中的每一个例子都是以某种形式出现的数字。
Like a lot of programmers, the only math I use is from discrete and combinatorial mathematics, and usually that's not math I program in an explicit way. I'm really missing some compelling examples of functional alternatives/supplements to regular oo algorithms.
像许多程序员一样,我使用的唯一数学来自离散和组合数学,通常这不是我以明确方式编程的数学。我真的错过了一些令人信服的示例,这些示例是常规 oo 算法的功能替代/补充。
What are some non-numerical use-cases for functional programming ?
函数式编程有哪些非数字用例?
回答by Juliet
My company asked me to write a custom application that allowed users to perform ad hoc queries against a flat-file database. The users of this app were your typical Joe Businessman types. They are not programmers, and its unlikely they have ever seen an SQL statement in their lives.
我的公司要求我编写一个自定义应用程序,允许用户对平面文件数据库执行临时查询。这个应用程序的用户是典型的乔商人类型。他们不是程序员,他们在生活中不太可能见过 SQL 语句。
As a result, I was tasked to develop a friendly userinterface that would allow users to select columns, tables, conditions, etc to build up a query. This is challenging because I can represent the SQL statement in the UI without first creating an abstract representation of it in memory.
因此,我的任务是开发一个友好的用户界面,允许用户选择列、表、条件等来构建查询。这是具有挑战性的,因为我可以在 UI 中表示 SQL 语句,而无需先在内存中创建它的抽象表示。
The first iteration was written in C#. I created a boatload classes to represent the abstract syntax of an SQL statement, which resulted in a really cumbersome object model:
第一次迭代是用 C# 编写的。我创建了一个船载类来表示 SQL 语句的抽象语法,这导致了一个非常麻烦的对象模型:
- a Join class, a Joins collection class
- a WhereClause class, a WhereClauses collection class
- a SelectedColumn class, SelectedColumns collection class
- an OrderBy class, OrderBy collection collections class
- an SqlStatement class that grouped all of the aforemtioned classes together
- 一个 Join 类,一个 Joins 集合类
- 一个 WhereClause 类,一个 WhereClause 集合类
- SelectedColumn 类,SelectedColumns 集合类
- 一个 OrderBy 类,OrderBy 集合集合类
- 一个 SqlStatement 类,它将所有 aforemtioned 类组合在一起
Converting an SqlStatement instance to a string was gloriously painful, ugly, and buggy. Moving the oppositive direction, from string to SqlStatement, was even worse, as it broke apart the pieces of an SQL string using lots of regex and string manipulation.
将 SqlStatement 实例转换为字符串是极其痛苦、丑陋和错误的。将相反的方向从字符串移动到 SqlStatement,甚至更糟,因为它使用大量正则表达式和字符串操作分解了 SQL 字符串的各个部分。
I hacked together the system, produced an application that worked, but I wasn't very happy with it. I especially wasn't happen when the business requirements of the app changed on me, which forced me to revisit my C# code.
我对系统进行了黑客攻击,生成了一个有效的应用程序,但我对此并不满意。当应用程序的业务需求对我发生变化时,我尤其不会发生这种情况,这迫使我重新访问我的 C# 代码。
Just as an experiment, I rewrote my SqlStatement in F# and represented it as a union:
作为一个实验,我在 F# 中重写了我的 SqlStatement 并将其表示为联合:
type dir = Asc | Desc
type op = Eq | Gt | Gte | Lt | Lte
type join = Inner | Left | Right
type sqlStatement =
| SelectedColumns of string list
| Joins of (string * join) list
| Wheres of (string * op * string) list
| OrderBys of (string * dir) list
type query = SelectedColumns * Joins * Wheres * OrderBys
That small amount of code replaced a few hundred lines of C# and a dozen or so classes. More importantly, pattern matching simplified the process required to convert abstract representation into an SQL string.
少量的代码取代了几百行 C# 和十几个类。更重要的是,模式匹配简化了将抽象表示转换为 SQL 字符串所需的过程。
The fun part was converting an SQL string back into a query object using fslex/fsyacc.
有趣的部分是使用 fslex/fsyacc 将 SQL 字符串转换回查询对象。
If I remember correctly, the original C# code totalled 600 lines and around a dozen classes, lots of messy regex, and requied two days to write and test. By comparison, the F# code consisted of one .fs file of around 40 lines, 100 lines or so to implement the lexer/parser, and consumed a few hours out of my day to test.
如果我没记错的话,原来的 C# 代码总共有 600 行和大约十几个类,还有很多乱七八糟的正则表达式,并且需要两天时间来编写和测试。相比之下,F# 代码由一个大约 40 行的 .fs 文件组成,其中 100 行左右用于实现词法分析器/解析器,并且在我一天中花费了几个小时来进行测试。
Seriously, writing this part of the app in F# felt like cheating, that's how trivially easy it was.
说真的,用 F# 编写应用程序的这一部分感觉就像在作弊,那是多么简单。
回答by Diomidis Spinellis
We used Haskell to implement a domain-specific language for describing, pricing, and monitoring exotic derivatives.
我们使用 Haskell 实现了一种用于描述、定价和监控奇异衍生品的领域特定语言。
回答by Mark Cidade
Functional programming is a paradigm like procedural/structured, object-oriented, and generic/templated programming are. It's turing-complete so you can do anything you want.
函数式编程是一种范式,类似于过程/结构化、面向对象和泛型/模板化编程。它是图灵完备的,所以你可以做任何你想做的事情。
Aside from math and science, it's makes it easier for parser combinators, artifical intelligence, concurrency, dynamic evaluation, co-routines, continuations, terse notation (faster brain-to-keyboard-to-text-file cycle and less code to maintain), strongly-typed parametization (see Haskell's algebraic types) and dynamic self-reflection (e.g., minimalistic metacircular interpreters with a REPL).
除了数学和科学之外,它还使解析器组合器、人工智能、并发、动态评估、协同例程、延续、简洁符号(更快的大脑到键盘到文本文件的循环和更少的代码维护)变得更容易,强类型参数化(参见 Haskell 的代数类型)和动态自我反思(例如,带有 REPL 的简约元循环解释器)。
回答by BobbyShaftoe
You might be interested in hearing this episode of Software Engineering Radio with the creator of Erlang, who developed it while working for Ericsson.
您可能有兴趣与 Erlang 的创建者一起收听软件工程广播的这一集,他在为爱立信工作时开发了它。
http://www.se-radio.net/podcast/2008-03/episode-89-joe-armstrong-erlang
http://www.se-radio.net/podcast/2008-03/episode-89-joe-armstrong-erlang
回答by Juliet
Got another one for you:
再给你一个:
I'm involved in the very early stages of prototyping a suite of new enterprise-scale financial products intended for small-to-medium sized banks, local government, stock exchanges, etc. You're probably thinking "oh, financial code, you must be doing a lot of math" -- actually, no. These products are intended to be highly customizable and allow users to inject business rules at strategic points in the application.
我参与了为中小型银行、地方政府、证券交易所等设计的一套新的企业级金融产品原型的早期阶段。你可能在想“哦,金融代码,你一定是在做很多数学运算”——实际上,没有。这些产品旨在高度可定制,并允许用户在应用程序的战略点注入业务规则。
We're using F# to represent and interpret business rules. To use a naive example, lets we're writing some code for check processing, we might write the rules like this:
我们使用 F# 来表示和解释业务规则。举个简单的例子,让我们写一些代码来处理支票,我们可能会写这样的规则:
type condition =
| Test of string
| And of condition * condition
| Or of condition * condition
| Not of condition
type transactionWorkflow =
| Reject
| Approve
| AdministratorOverride of string
| If of condition * transactionWorkflow list
(* condition, true condition *)
| IfElse of condition * transactionWorkflow list * transactionWorkflow list
(* condition, true condition, false condition *)
| AttachForms of string list
Using a special application, users can write some business rules represented by the structure above. For example:
使用特殊的应用程序,用户可以编写一些由上述结构表示的业务规则。例如:
let checkProcessingWorkflow =
[If(Test("account doesn't exist")
,[AdministratorOverride("Account doesn't exist. Continue?");
AttachForms ["40808A - Null Account Deposit"]]
);
If(Test("deposit > 10000")
,[
If(And(Test("account created within 3 months")
,Test("out of country check"))
,[Reject]);
IfElse(Test("account state = TX")
,[AttachForms ["16A"; "16B"]]
,[AttachForms ["1018"]]
)
]
);
Approve
]
So, rather than writing one business-rules engine to rule them all, we handle certain processes as a very tiny domain-specific language intepreted by F#. I'm hoping this approach will allow us to design very simple business-readable DSLs without needed to detect conflicting rules.
因此,我们不是编写一个业务规则引擎来管理所有流程,而是将某些流程作为一种由 F# 解释的非常小的领域特定语言来处理。我希望这种方法能让我们设计出非常简单的业务可读 DSL,而无需检测冲突规则。
Of course, everything above is just concept-code, and we're still in the very earlier stages of even prototyping one of our rules system. We're using F# rather than Java or C# for one particular reason: pattern matching.
当然,以上所有内容都只是概念代码,我们甚至还处于对我们的规则系统之一进行原型设计的早期阶段。我们使用 F# 而不是 Java 或 C# 是出于一个特殊的原因:模式匹配。
回答by Chris Conway
"Getting Started with Erlang"has an extensive client/server example (starting in Section 1.3.5) which may suit your needs.
“Erlang 入门”有一个广泛的客户端/服务器示例(从第 1.3.5 节开始),可能适合您的需求。
回答by Charlie Martin
The more I use a functional style, the better I like it. Consider this Python fragment from another question:
我越是使用功能性风格,我就越喜欢它。考虑来自另一个问题的这个 Python 片段:
>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]
This is admittedly a more or less mathematical statement, but there are lotsof generators in Python. Once you get used to it, using a list comprehension in place of a loop is both easy to understand, and less likely to have a bug (you don't get "off by one" bugs.)
这无疑是一个或多或少的数学陈述,但Python 中有很多生成器。一旦习惯了,使用列表推导式代替循环既容易理解,又不太可能出现错误(您不会“逐一”解决错误。)
回答by John D. Cook
Check out Text Processing in Python. The book starts out with some simple but well-motivated examples where functional programming techniques make code easier to read and more likely to be correct.
查看Python 中的文本处理。本书从一些简单但动机良好的示例开始,在这些示例中,函数式编程技术使代码更易于阅读且更可能是正确的。
回答by Pavel Minaev
These days, I wouldn't even consider writing a DSL lexer/parser in a non-functional language (in broad sense of the term). ADTs and pattern matching make it so much easier.
现在,我什至不会考虑用非函数式语言(广义上的术语)编写 DSL 词法分析器/解析器。ADT 和模式匹配使它变得更加容易。
回答by Magnus
It's true that many books on functional programming uses "numerical programming" to teach, but there are exceptions.
诚然,很多关于函数式编程的书籍都使用“数值编程”来教授,但也有例外。
Haskell School of Expressionis a beginner's book on Haskell that uses multimedia as its vehicle for teaching.
Haskell School of Expression是一本关于 Haskell 的初学者书籍,它使用多媒体作为教学工具。
Real World Haskelldoesn't really have any particular vehicle throughout the entire book, but there are several chapters covering writing "real" programs in a functional style.
Real World Haskell在整本书中并没有真正使用任何特定工具,但是有几章涵盖了以函数式风格编写“真实”程序的内容。

