F# 什么';它是if-then语句的功能替代品?
我一直在学习F#和函数式编程,并试图用函数式的方式做事。然而,当涉及到重写一些我已经用C语言编写的代码时,我会被简单的if-then语句(那些只做某事,不返回值的语句)所困扰。我知道你可以在F#完成这件事: 然而,我认为这是一种必要的编码方法?也许我对函数式编程的了解还不够,但对我来说它似乎不实用。我认为函数式方法是组合函数和表达式,而不是简单地一个接一个地执行语句,这似乎鼓励了if 那么,我是否遗漏了一些东西,如果在功能世界中,它是完美的呢?如果不是,这类语句的功能等价物是什么?我怎样才能接受一个if,然后将其功能化呢 编辑:我可能问了一个错误的问题(抱歉,对函数编程来说还是相当新的):让我们举一个真实的例子,让我甚至问:F# 什么';它是if-then语句的功能替代品?,f#,functional-programming,F#,Functional Programming,我一直在学习F#和函数式编程,并试图用函数式的方式做事。然而,当涉及到重写一些我已经用C语言编写的代码时,我会被简单的if-then语句(那些只做某事,不返回值的语句)所困扰。我知道你可以在F#完成这件事: 然而,我认为这是一种必要的编码方法?也许我对函数式编程的了解还不够,但对我来说它似乎不实用。我认为函数式方法是组合函数和表达式,而不是简单地一个接一个地执行语句,这似乎鼓励了if 那么,我是否遗漏了一些东西,如果在功能世界中,它是完美的呢?如果不是,这类语句的功能等价物是什么?我怎样才能接受
if not <| System.String.IsNullOrWhiteSpace(data) then do
let byteData = System.Text.Encoding.Unicode.GetBytes(data)
req.ContentLength <- int64 byteData.Length
let postStream : System.IO.Stream = req.GetRequestStream()
postStream.Write(byteData, 0, byteData.Length)
postStream.Flush()
postStream.Dispose()
if-not在函数世界中,if-then没有什么问题
您的示例实际上类似于let=expr
,因为expr
有副作用,我们忽略其返回值。一个更有趣的例子是:
if cond then expr
这相当于:
match cond with
| true -> expr
| false -> ()
如果我们使用模式匹配
当条件很简单或只有一个条件表达式时,if-then比模式匹配更具可读性。此外,值得注意的是,函数式编程中的一切都是表达式。所以if cond then expr
实际上是if cond then expr else()
的快捷方式
如果then本身不是强制性的,那么使用If then作为陈述是一种强制性的思维方式。根据我的经验,函数式编程更多的是关于思维方式,而不是编程语言中的具体控制流
编辑:
您的代码完全可读。一些次要问题是去除冗余的do
关键字、类型注释和postStream.Dispose()
(通过使用use
关键字):
if not命令不是if表达式,而是if表达式中的内容。例如,let abs num=if num<0然后-num else num
是编写abs函数的一种完全实用的方法。它接受一个参数并返回该参数的转换,没有任何副作用。但是当你有“只做某件事而不返回值的代码”时,你就在写一些不完全是功能性的东西。函数式编程的目标是最小化程序中可以这样描述的部分。如何编写条件语句是相切的。为了编写复杂的代码,您需要在某个点进行分支。实现这一点的方法非常有限,所有这些方法都需要通过一段代码的逻辑流。如果您想避免使用If/then/else,则可以使用loop/while/repeat进行欺骗,但这将使您的代码在维护和读取时变得不合理
函数式编程并不意味着你不应该一个接一个地执行语句——它只是意味着你不应该有一个可变的状态。每个函数在每次调用时都需要以相同的方式可靠地运行。数据处理方式的任何差异都需要由传入的数据来解释,而不是对调用函数的任何对象隐藏的触发器
例如,如果我们有一个函数foo(int,bool)
,它根据bool
是真是假返回不同的结果,那么foo()
中几乎肯定会有一个if
语句。这是完全合法的。不合法的是使用一个函数foo(int)
,该函数根据是否是第一次在程序中调用而返回不同的内容。这是一个“有状态”函数,它使任何人都难以维护程序。如果您的if
语句具有返回值且没有副作用,则该函数被视为功能性函数
假设您想编写以下等效内容:
如果(x>3)n=3;否则n=x代码>
使用if命令中的return语句,而不是执行此操作:
设n=(如果x>3,则为3,否则为x)
假设的如果突然起作用,因为它没有副作用;它只返回一个值。把它想象成某些语言中的三元运算符:intn=x>3?3:x代码>到目前为止还没有提到的一个重要问题是,if。。然后。。else
和如果。。然后
而不使用else
分支
函数式语言中的If
if
的功能解释是,它是一个计算结果为某个值的表达式。要计算if c然后e1 else e2
的值,请计算条件c
,然后根据条件计算e1
或e2
。这将为您提供if。。然后。。else
如果您只有如果c然后e
,那么如果c
为false
,您就不知道评估的结果应该是什么,因为没有其他
分支!以下内容显然毫无意义:
let num = if input > 0 then 10
在F#中,具有副作用的表达式,如printf“hi”
返回类型为unit
的特殊值。该类型只有一个值(写为()
),因此您可以编写if
,它只在一种情况下起作用:
let u = if input > 0 then printf "hi" else ()
它的计算结果总是unit
,但在true
分支中,它也会产生副作用。在false
分支中,它只返回一个unit
值。在F#中,你不需要
let num = if input > 0 then 10
let u = if input > 0 then printf "hi" else ()
let u = if input > 0 then printfn "hi"
maybeData |> Option.iter (fun data ->
let byteData = System.Text.Encoding.Unicode.GetBytes(data)
req.ContentLength <- int64 byteData.Length
use postStream = req.GetRequestStream()
postStream.Write(byteData, 0, byteData.Length) )
function $if(param) {
return new Condition(param)
}
function Condition(IF, THEN, ELSE) {
this.call = function(seq) {
if(this.lastCond != undefined)
return this.lastCond.call(
sequence(
this.if,
this.then,
this.else,
(this.elsif ? this.elsif.if : undefined),
seq || undefined
)
);
else
return sequence(
this.if,
this.then,
this.else,
(this.elsif ? this.elsif.if : undefined),
seq || undefined
)
}
this.if = IF ? IF : f => { this.if = f; return this };
this.then = THEN ? THEN : f => { this.then = f; return this };
this.else = ELSE ? ELSE : f => { this.else = f; return this };
this.elsif = f => {this.elsif = $if(f); this.elsif.lastCond = this; return this.elsif};
}
function sequence(IF, THEN, ELSE, ELSIF, FINALLY) {
return function(val) {
if( IF(val) )
return THEN();
else if( ELSIF && ELSIF(val) )
return FINALLY(val);
else if( ELSE )
return ELSE();
else
return undefined
}
}}
var eq = val => x => x == val ? true : false;
$if( eq(128) ).then( doStuff ).else( doStuff )
.elsif( eq(255) ).then( doStuff ).else( doStuff ).call();
sequence(f, f, f, f,
sequence(f, f, f, f
sequence(f, f, f)
)
);