1
    let csvList startDelim endDelim lst memF = 
        let listIter (listStr: string) item = 
            if listStr.Length > 0 then 
                listStr + "," + (memF item)
            else 
                memF item                
        startDelim + (List.fold listIter "" lst) + endDelim

    let listIntoJsonArray = csvList "[" "]"
    let listIntoJsonObject = csvList "{" "}"

    let intConverter (item:int) : string =
        item.ToString()

    let objectConverter (item:SomeObject) : string =
        item.value.ToString()

    let objects = [{vaue: 12.3}; {vaule: 33.2}]
    let ints = [1;2;4]

    let o = listIntoJsonObject objects objectConverter
    let i = listIntoJsonObject ints intConverter 

I can't seem to find the magic sauce to make the csvList or its partially applied helpers listIntoJsonArray or listIntoJsonObject generic.

Thanks for the help.

Brian
  • 117,631
  • 17
  • 236
  • 300
akaphenom
  • 6,728
  • 10
  • 59
  • 109

3 Answers3

6

Your listIntoJsonArray and listIntoJsonObject are values, not functions, so you met value restriction monster. You can either convert them to functions by adding explicit argument or to type functions.

// function case

let csvList startDelim endDelim lst memF = 
    let listIter (listStr: string) item = 
        if listStr.Length > 0 then 
            listStr + "," + (memF item)
        else 
            memF item                
    startDelim + (List.fold listIter "" lst) + endDelim

let listIntoJsonObject x = csvList "{" "}" x

let ints = [1;2;4]

let i = listIntoJsonObject [1;2;4] string 
let y = listIntoJsonObject ["123"] id


// type function case

let csvList<'T> startDelim endDelim (lst : 'T list) memF = 
    let listIter (listStr: string) item = 
        if listStr.Length > 0 then 
            listStr + "," + (memF item)
        else 
            memF item                
    startDelim + (List.fold listIter "" lst) + endDelim

[<GeneralizableValue>]
let listIntoJsonObject<'T> = csvList<'T> "{" "}"

let ints = [1;2;4]

let i = listIntoJsonObject [1;2;4] string 
let y = listIntoJsonObject ["123"] id
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
desco
  • 16,642
  • 1
  • 45
  • 56
4

I haven't tried the code, but in general, eta-conversion, e.g. changing

let myFunVal = partialApplication toSomeArgs

to

let myFun rest = partialApplication toSomeArgs rest

is likely to fix this.

Brian
  • 117,631
  • 17
  • 236
  • 300
2

csvList looks generic enough: string -> string -> 'a list -> ('a -> string) -> string

But you've encountered Value Restriction in your attempt at partial application with listIntoJsonArray and listIntoJsonObject; you need to add explicit parameters:

let listIntoJsonArray lst memF = csvList "[" "]" lst memF
let listIntoJsonObject lst memF = csvList "{" "}" lst memF
Community
  • 1
  • 1
Stephen Swensen
  • 22,107
  • 9
  • 81
  • 136
  • Didn't seemt to do the trick. Just when I feel like I am gettng a solid hold on the language it takes another turn. Will need to research the Value Restrictions more... Thx. – akaphenom Nov 18 '10 at 16:55
  • @akaphenom: my original solution had a mistake (I added the parameters to the function definition, but then didn't pass them as arguments to csvList), it should work correctly now. F# is a wild beast, but that makes the taming so much more exciting, and the rewards so much greater :) – Stephen Swensen Nov 18 '10 at 17:18