I have the following nested Seq.map() calls in a function that compiles and works effectively:
|> Seq.map (fun (tradedOnKey : DateTime, portfolioSeq : seq<PortfolioId * seq<PortfolioFundRecord>>) ->
let pricedPortfoliosGroup =
portfolioSeq
|> Seq.map (fun (p : PortfolioId, spsf : (seq<PortfolioFundRecord>)) ->
let price =
spsf
|> Seq.map (fun (pfr : PortfolioFundRecord) -> pfr.Fund.ClosingPrice * float pfr.PortfolioWeight / 100.0)
|> Seq.reduce (+)
let topPortfolioFundRecord = spsf |> Seq.head
{ PortfolioId = p; Price = price; TradedOn = topPortfolioFundRecord.Fund.TradedOn }
)
(tradedOnKey, pricedPortfoliosGroup)
)
which prompts the following lint warning:
Lint:
Seq.map f (Seq.map g x)
might be able to be refactored intoSeq.map (g >>f) x
.
I believe the warning is prompted by these top 2 map calls:
|> Seq.map (fun (tradedOnKey : DateTime, portfolioSeq : seq<PortfolioId * seq<PortfolioFundRecord>>) ->
let pricedPortfoliosGroup =
portfolioSeq
|> Seq.map (fun (p : PortfolioId, spsf : (seq<PortfolioFundRecord>)) ->
but I don't know how to refactor them since my 2nd parameter is a sequence and I want to "transform it" but not flatten it.
Can you suggest a way to do that? I also looked for a way to turn off the lint warning just for that code fragment but the power tools do not seem to offer a way to do that.
Here's the whole function for completeness sake:
let getPortfoliosPrices(dbFundsWithPortfolioFunds : (DbFunds * DbPortfolioFunds) Linq.IQueryable)(takenDays: int) =
let portfolioPrices =
dbFundsWithPortfolioFunds
|> Seq.collect(fun (f : DbFunds, fp : DbPortfolioFunds) ->
takenDays |> getStockPrices f.Symbol
|> Seq.map(fun(quote : FundQuote) ->
let portfolioFundRec = {PortfolioId = fp.PortfolioId; PortfolioWeight = fp.Weight; Fund = quote}
portfolioFundRec)
)
|> Seq.groupBy(fun (portfolioFundRec : PortfolioFundRecord) -> portfolioFundRec.Fund.TradedOn)
|> Seq.map(fun (tradedOnKey : DateTime, spfr : PortfolioFundRecord seq) ->
let gpfr = spfr |> Seq.groupBy (fun(pfr : PortfolioFundRecord)->pfr.PortfolioId)
(tradedOnKey, gpfr)
)
|> Seq.map (fun (tradedOnKey : DateTime, portfolioSeq : seq<PortfolioId * seq<PortfolioFundRecord>>) ->
let pricedPortfoliosGroup =
portfolioSeq
|> Seq.map (fun (p : PortfolioId, spsf : (seq<PortfolioFundRecord>)) ->
let price =
spsf
|> Seq.map (fun (pfr : PortfolioFundRecord) -> pfr.Fund.ClosingPrice * float pfr.PortfolioWeight / 100.0)
|> Seq.reduce (+)
let topPortfolioFundRecord = spsf |> Seq.head
{ PortfolioId = p; Price = price; TradedOn = topPortfolioFundRecord.Fund.TradedOn }
)
(tradedOnKey, pricedPortfoliosGroup)
)
portfolioPrices
In your second top-level Seq.map
, you are just passing tradedOnKey
through, and do something with your sequence. You could merge all that into one, by doing:
dbFundsWithPortfolioFunds
|> Seq.collect(fun (f : DbFunds, fp : DbPortfolioFunds) ->
takenDays |> getStockPrices f.Symbol
|> Seq.map(fun(quote : FundQuote) ->
let portfolioFundRec = {PortfolioId = fp.PortfolioId; PortfolioWeight = fp.Weight; Fund = quote}
portfolioFundRec)
)
|> Seq.groupBy(fun portfolioFundRec-> portfolioFundRec.Fund.TradedOn)
|> Seq.map(fun (tradedOnKey, spfr) ->
let gpfr = spfr |> Seq.groupBy (fun pfr -> pfr.PortfolioId)
let pricedPortfoliosGroup =
gpfr
|> Seq.map (fun (p, spsf) ->
let price =
spsf
|> Seq.sumBy (fun pfr -> pfr.Fund.ClosingPrice * float pfr.PortfolioWeight / 100.0)
let topPortfolioFundRecord = spsf |> Seq.head
{ PortfolioId = p; Price = price; TradedOn = topPortfolioFundRecord.Fund.TradedOn }
)
(tradedOnKey, pricedPortfoliosGroup)
)
This should get rid of the warning (difficult to verify because I don't have all the type definitions for a full repro).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With