如何使我的功能通用

时间:2010-11-18 16:15:14

标签: generics f# value-restriction

    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 

我似乎无法找到使csvList或其部分应用的助手listIntoJsonArray或listIntoJsonObject通用的神奇酱油。

感谢您的帮助。

3 个答案:

答案 0 :(得分:6)

你的listIntoJsonArray和listIntoJsonObject是值,而不是函数,所以你遇到了value restriction怪物。您可以通过添加显式参数或键入函数将它们转换为函数。

// 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

答案 1 :(得分:4)

我没有尝试过代码,但一般来说,eta转换,例如改变

let myFunVal = partialApplication toSomeArgs

let myFun rest = partialApplication toSomeArgs rest

很可能解决这个问题。

答案 2 :(得分:2)

csvList看起来很通用:string -> string -> 'a list -> ('a -> string) -> string

但您尝试使用listIntoJsonArraylistIntoJsonObject进行部分申请时遇到了Value Restriction;你需要添加显式参数:

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