用F#解决问题。将函数附加到类型的正确方法是什么?

时间:2017-05-17 11:40:12

标签: f# f#-interactive

我无法理解下面的代码有什么问题:

let toClass (problem:Problem<'a>) (classID:int) (items:'a list) =
        let newFreqTable = (problem.FreqTables.[classID]).count items
        { problem with FreqTables = newFreqTable :: (problem.FreqTables |> List.filter (fun i -> i.ClassID <> classID)) }
type Problem<'a> when 'a : equality with member this.toClass (classID:int) (items:list<'a>) = toClass this classID items

我有Problem类型,这只是一种分组任意数量FreqTables的方法 - “频率表”的缩写。所以toClass方法只需要适当的freqTable(通过classID参数)并返回一个新的 - 用计算的给定项。

let typeIndependentCall = toClass p 0 ["word"; "word"; "s"] // this works perfectly

let typeDependentCall = typeIndependentCall.toClass 1 ["word"; "s"] 
// gives an error: "One or more of the overloads of this method has 
// curried arguments. Consider redesigning these members to take 
// arguments in tupled form".

我对F#和函数式编程很新。将行为附加到我的类型的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

在F#中,有两种主要方法可以将参数传递给函数:curried和tupled。咖喱表单是您在上面的代码中使用的,并且有一些关键的好处,首先是部分应用。

例如,而不是想到

from dateutil import parser
parsed_date = parser.parse(date)

作为一个接受2个参数并返回值的函数,我们可以将其视为一个参数的函数,该参数返回一个带有一个参数的函数。这就是我们函数的类型签名

的原因
fun add a b = a + b

或者更清楚地说,

Int -> Int -> Int

但是,当重载方法时,我们只能使用tupled参数形式

Int -> (Int -> Int)

原因是优化,正如here

所述

要使代码正常工作,请使用

(Int, Int) -> Int

并称之为:

type Problem<'a> when 'a : equality with member this.toClass (classID:int, items:list<'a>) = toClass this classID items