我刚刚开始看看Haskell(我之前的FP体验是在Scheme中),我遇到了这段代码:
do { putStrLn "ABCDE" ; putStrLn "12345" }
Run Code Online (Sandbox Code Playgroud)
对我来说,这是程序式编程,如果有的话 - 特别是因为副作用的连续性.
有人请说明这段代码在任何方面都是"功能性的"吗?
关于JavaScript中的函数式编程理论有很多很好的文章.有些甚至包含代码示例,显示了命令式/面向对象编程和声明/函数式编程之间的区别.但我发现没有一个能够通过简单的JavaScript代码示例来展示如何处理Web应用程序中的副作用.没有现实世界的应用程序可以完全避免的副作用(数据库调用,登录到控制台,保存到一个文件,绘制到屏幕等),我有一个很难弄清楚它是如何在实践中完成的.
有博客文章和S/O答案(如下所示:如何在纯函数式编程中执行副作用?)触及现实世界中处理副作用的主题,但它们通常远非简单,不要包括代码示例或包含其他语言的代码示例(Haskell,Scala等).我没有为Node/JavaScript找到一个.
所以...给出以下非常简单的带有MongoDB数据库的Node/Express应用程序示例,必须实现哪些代码更改,以便这段代码完全反映当前的JavaScript函数编程最佳实践.特别是涉及处理数据库调用的路由/函数时.我希望你的答案能够帮助我和其他人更好地理解功能编程的"避免副作用"概念在实际JavaScript中的实际应用.
/*app.js*/
const express = require('express')
const app = express()
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var greetingSchema = mongoose.Schema({
greeting: String
});
var Greeting = mongoose.model('Greeting', greetingSchema);
app.get('/', function (req, res) {
Greeting.find({greeting: 'Hello World!'}, function (err, greeting){
res.send(greeting);
});
});
app.post('/', function (req, res) {
Greeting.create({greeting: 'Wasssssssssssuuuuppppp'}, function (err, greeting){
res.send(greeting);
});
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
Run Code Online (Sandbox Code Playgroud) 我正在为Haskell中的简单命令式语言编写编译器,输出Java字节码.我已经到了我发出字节码的抽象表示的地步.
在编写用于编译if语句的代码时遇到了一些麻烦.要实现if语句,我需要跳转到标签.因此,我需要为该标签生成一个名称,该名称必须是唯一的.
我的第一个想法是通过一些状态compileStatement,即
compileStatement :: Statement -> UniqueIDState -> [AbstractInstruction]
Run Code Online (Sandbox Code Playgroud)
当然,compilerStatement是递归的,所以使用这种方法需要我从递归调用中将唯一ID生成器的状态传递回upp:
compileStatement :: Statement -> UniqueIDState -> (UniqueIdState, [AbstractInstruction])
Run Code Online (Sandbox Code Playgroud)
这看起来有点笨拙,特别是如果我意识到我需要在将来携带更多状态; 有更优雅的方式吗?
我是 Haskell 编程语言的新手,我一直在将IO类型作为函数参数或返回类型绊倒。
playGame :: Screen -> IO ()
Run Code Online (Sandbox Code Playgroud)
或者
gameRunner :: IO String -> (String -> IO ()) -> Screen -> IO ()
Run Code Online (Sandbox Code Playgroud)
这是如何工作的,我有点困惑,因为我知道 String 需要单词而 Int 需要数字。IO函数中使用的什么是期望或返回?
我试图从第一原则来理解函数式编程,但我仍然停留在纯函数世界和具有状态和副作用的不纯现实世界之间的接口上。从数学的角度来看,
详细说明:在我的理解中,纯函数是从域到共域的映射。最终,它是从计算机内存中的某些值到内存中的某些其他值的映射。在函数式语言中,函数是声明式定义的;即,它们描述了映射,但不描述需要对特定输入值执行的实际计算;后者由编译器来推导。在具有空闲内存的简化设置中,运行时将没有计算;相反,编译器可以在编译时为每个函数创建一个查找表。执行一个纯程序相当于查表。因此,组合函数相当于构建更高维的查找表。当然,拥有计算机的全部意义在于设计出无需逐点查找表即可指定函数的方法 - 但我发现心智模型有助于区分纯函数和效果。但是,我很难将这种心智模型应用于高阶函数:
现在到令人讨厌的现实世界。与它的交互并不纯粹,但没有它,就没有合理的程序。在我上面的简化心智模型中,分离程序的纯部分和不纯部分意味着每个函数式程序的基础是一层命令式语句,这些语句从现实世界中获取数据,对其应用纯函数(进行查表),以及然后将结果写回现实世界(磁盘、屏幕、网络等)。
在 Haskell 中,这种与现实世界的命令式交互被抽象为IO 操作,编译器根据它们的数据依赖性对它们进行排序。但是,我们不会直接将程序编写为一系列命令式 IO 操作。相反,有些函数会返回 IO 操作(类型为 的函数:: IO a)。但据我所知,这些不可能是真正的功能。这些是什么?如何根据上面概述的心智模型最好地思考它们?
io haskell functional-programming purely-functional higher-order-functions