首页 > 解决方案 > F#:在列表中乘以负数的更优雅的方法

问题描述

对不起,愚蠢的问题,我真的是 f# 的新手。我想编写一个函数来将列表中的负数相乘。但现在我的功能并不完美。

let rec mulOfNegs = function
    | [] -> 0
    | x::t when x < 0 -> x * if mulOfNegs t <> 0 then mulOfNegs t else 1
    | _::t -> mulOfNegs t

mulOfNegs [2;3;-1;-2;-3]

当然,有很多方法可以优化函数(创建多个函数,使用一些变量等),但我不知道哪一种更好,更“实用”。

标签: functional-programmingf#

解决方案


  1. 空集的乘积是 1 而不是 0。

  2. 您正在使用 hack 解决这个问题(认识到如果mulOfNegs t = 0它是错误的,应该用 1 替换)。该实现表现不佳,因为它两次评估 mulOfNegs,使您的函数 O(2^n) 而不是 O(n)。

  3. 一旦你更正了 1. 并删除了 hack,你应该有一个工作功能。但是您可以通过分成两部分来使其更易于理解:

let rec productOfNegs = function
    | [] -> 1
    | x::t ->
        if x < 0 then x * productOfNegs t else productOfNegs t

// Alternatively
let productOfNegs =
    let product = List.fold (*) 1
    List.filter (fun x -> x < 0) >> product

推荐阅读