Scott Nimrod
Scott Nimrod

Reputation: 11570

Unable to use List.sum with a transformation

I am unable to figure out the syntax required for running an aggregator on a function that performs a transformation.

I have the following code:

type Suit = | Spades| Clubs | Diamonds | Hearts

type Face = | Two | Three | Four | Five 
            | Six | Seven | Eight | Nine | Ten
            | Jack | Queen | King | Ace

type Card = {Face:Face; Suit:Suit}

I am unable to get this function to compile:

let getCount (hand:Card list) =
    let getFaceValue face =
        match face with
        | Two -> 2
        | Three -> 3
        | Four -> 4
        | Five -> 5
        | Six -> 6
        | Seven -> 7
        | Eight -> 8
        | Nine -> 9
        | Ten -> 10
        | Jack -> 10
        | Queen -> 10
        | King -> 10
        | Ace -> 11

    let sumOfHand = hand |> List.sum (fun c -> getFaceValue c.Face)
    sumOfHand

Expecting a type supporting the operator '+' but given a function type. You may be missing an argument to a function.

Why am I getting this error and what can I do to use a transformation within an aggregate function?

Upvotes: 0

Views: 47

Answers (2)

Jakub Lortz
Jakub Lortz

Reputation: 14904

List.sum takes a single parameter (a list) and uses + operator to calculate the sum of all elements.

To sum by a function applied to each element of the list, use List.sumBy

let sumOfHand = hand |> List.sumBy (fun c -> getFaceValue c.Face)

Upvotes: 4

Caridorc
Caridorc

Reputation: 6661

You should map first then sum

hand |> List.map (fun x ...) |> List.sum

Upvotes: 2

Related Questions