什么是if-then语句的功能替代? [英] What's a functional replacement for if-then statements?

查看:631
本文介绍了什么是if-then语句的功能替代?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在学习F#和函数式编程,并试图以功能的方式来做事情。然而,当重写一些我已经用C#编写的代码时,我陷入了简单的if-then语句(那些只做某事而不返回值的语句)。我知道你可以在F#中取消它:

  if expr then do()

然而,我认为这是编码的必要方法?也许我没有足够的关于函数式编程的知识,但它对我来说似乎不起作用。我认为功能方法是编写函数和表达式,而不是简单地依次执行语句,这是如果 - 然后似乎鼓励。



所以,我是否缺少如果 - 那么在功能世界中是完美的吗?如果不是,这种说法的功能等同是什么?编辑:我可能会问一个错误的问题(对不起,函数式编程还是相当新的):让我们来看看如何使用if-then并将其转换为函数?拿一个真实世界的例子,让我问这个:

 如果不是< | System.String.IsNullOrWhiteSpace(data)然后做
让byteData = System.Text.Encoding.Unicode.GetBytes(data)
req.ContentLength< - int64 byteData.Length
let postStream:
postStream.Write(byteData,0, / code>

这个if-body的主体不会返回任何东西,但我不知道如何让这个功能更多(如果这甚至可能)。我不知道使命令式代码最小化的正确技术。鉴于F#的本质,直接运输我的C#是相当容易的,但我很难将其转化为功能。每当我在C#中遇到这样的if语句,并且我试图将它传递给F#时,我都感到灰心,我想不出让代码更加实用的方法。

解决方案

目前尚未提及的重要一点是 if if ... then .. else 如果..然后没有 else 分支。



< h3>如果在函数式语言中

if 的功能解释是它是一个表达式,其值为某个值。要评估的值,如果c然后e1 else e2 ,则评估条件 c ,然后评估 e1 e2 ,具体取决于条件。这给你 if的结果如果.. then .. else



如果你只有<$ c如果 c false ,因为没有 else 分支!以下显然没有意义:

  let num = if input> 0 then 10 

在F#中,具有类似 printf嗨返回类型 unit 的特殊值。这个类型只有一个值(写作()),所以你可以写 if 只是一个例子:

  let u = if input> 0 then printfhielse()

这总是计算为 unit ,但在 true 分支中,它也执行副作用。在 false 分支中,它只是返回一个单位值。在F#中,您不必手动编写 else()位,但概念上它仍然存在。你可以这样写:

  let u = if input> 0然后printfnhi



关于您的其他示例



代码对我来说看起来非常好。当你必须处理必要的API时(比如许多.NET库),那么最好的选择是使用这样的命令式功能,如果和<$ c

您可以使用各种调整,例如使用选项< string>来表示您的数据; (而不只是 string with null 或空字符串)。这样,您可以使用 None 来表示缺少的数据,其他任何内容都将是有效的输入。然后你可以使用一些更高级的函数来处理选项,比如 Option.iter ,如果有值,它会调用给定的函数:

  maybeData |> Option.iter(有趣的数据 - > 
let byteData = System.Text.Encoding.Unicode.GetBytes(data)
req.ContentLength< - int64 byteData.Length
use postStream = req .GetRequestStream()
postStream.Write(byteData,0,byteData.Length))

这并不是非常必要的,但它更具说明性,因为如果你自己不需要写 if 。顺便说一句:我还建议使用 use ,如果你想要 Dispose 对象。


I've been learning F# and functional programming and trying to do things the functional way. However, when it comes to rewriting some code I'd already written in C# I get stuck at simple if-then statements (ones that only do something, not return a value). I know you can pull this off in F#:

if expr then do ()

However, I thought this was an imperative approach to coding? Maybe I've not learned enough about functional programming, but it doesn't seem functional to me. I thought the functional approach was to compose functions and expressions, not simply execute statements one after the other which is what if-then seems to encourage.

So, am I missing something and if-then is perfectly fine in the functional world? If not, what is the functional equivalent of such a statement? How could I take an if-then and turn it functional?

Edit: I might've asked the wrong question (sorry, still fairly new to functional programming): Let's take a real world example that made me even ask this:

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()

The body of that if-then doesn't return anything, but I don't know how I could make this more functional (if that's even possible). I don't know the proper technique for minimizing imperative code. Given F#'s nature it's fairly easy to just transport my C# directly, but I'm having difficulties turning it functional. Every time I reach such an if statement in C#, and I'm trying to transport it to F#, I get discouraged that I can't think of a way to make the code more functional.

解决方案

An important point that hasn't been mentioned so far is the difference between if .. then .. else and if .. then without the else branch.

If in functional languages

The functional interpretation of if is that it is an expression that evaluates to some value. To evaluate the value of if c then e1 else e2 you evaluate the condition c and then evaluate either e1 or e2, depending on the condition. This gives you the result of the if .. then .. else.

If you have just if c then e, then you don't know what the result of the evaluation should be if c is false, because there is no else branch! The following clearly does not make sense:

let num = if input > 0 then 10

In F#, expressions that have side-effects like printf "hi" return a special value of type unit. The type has only a single value (written as ()) and so you can write if which does an effect in just a single case:

let u = if input > 0 then printf "hi" else ()

This always evaluates to unit, but in the true branch, it also performs the side-effect. In the false branch, it just returns a unit value. In F#, you don't have to write the else () bit by hand, but conceptually, it is still there. You can write:

let u = if input > 0 then printfn "hi"

Regarding your additional example

The code looks perfectly fine to me. When you have to deal with API that is imperative (like lots of the .NET libraries), then the best option is to use the imperative features like if with a unit-returning branch.

You can use various tweaks, like represent your data using option<string> (instead of just string with null or empty string). That way, you can use None to represent missing data and anything else would be valid input. Then you can use some higher-order functions for working with options, such as Option.iter, which calls a given function if there is a value:

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) )

This is not really less imperative, but it is more declarative, because you don't have to write the if yourself. BTW: I also recommend using use if you want to Dispose object auotmatically.

这篇关于什么是if-then语句的功能替代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆