擅长:python、mysql、java
<p>在Python中,一种常见的做法是在执行过程中对数据进行变异(“更改”、“更新”),就像处理<code>temp</code>列表一样,在每一步都对其进行变异。虽然即使在Python中也普遍不赞成它,但该语言本身使它非常简单,因此非常诱人</p>
<p>在F#中,变异数据仍然是可能的,但语言让它变得困难。故意地嗯,这不是很难的-只是几个额外的字符-但至少变异数据不是默认的。这通常是一种更好的方法,就连Python社区现在也认识到了这一点</p>
<p>相反,F#方式(以及通常的<em>功能</em>方式)不是变异数据,而是通过转换旧数据来创建新数据。在中,函数是做什么的(这里的“函数”指的是“数学函数”)</p>
<p>特别是,Python循环似乎正在做的是:(1)通过<code>i[0]</code>过滤</em>输入列表,然后(2)通过丢弃<code>i[0]</code>并只留下<code>i[1]</code>来转换(通常称为“映射”)每个元素,然后(3)排序。这可以用F#写成如下:</p>
<pre><code>let findMatches s l =
l
|> List.filter (fun (e1, _) -> e1 == s) // filtering
|> List.map (fun (_, e2) -> e2) // mapping
|> List.sort
</code></pre>
<p>该程序不是通过反复变异来“构建”列表,而是通过三次转换输入列表来创建结果列表:过滤、映射、排序。另一件需要注意的事情是,转换本身是由较小的部分组成的:整个列表的转换是通过转换单个元素来实现的</p>
<p>对于这样的简单情况(排序除外),F#还提供了特殊的语法,即所谓的“列表理解”。它是语法糖,它在幕后执行与上述类似的转换,但语法(可以说)更具可读性:</p>
<pre><code>let findMatches s l =
[ for e1, e2 in l do
if e1 == s then yield e2
]
|> List.sort
</code></pre>
<p>请注意,尽管这看起来与Python程序几乎相同,但其含义却略有不同。这个程序不是“做这个,然后做那个”(又名“命令式风格”),而是说“结果以这种方式取决于输入”(又名“功能性风格”)</p>