F# F中的停止字删除#

F# F中的停止字删除#,f#,f#-scripting,F#,F# Scripting,我正在尝试编写一个代码来删除字符串列表中的“the”、“this”等停止词 我写了这段代码: let rec public stopword (a : string list, b :string list) = match [a.Head] with |["the"]|["this"] -> stopword (a.Tail, b) |[] -> b |_ -> stopword (a.Tail, b@[a.Head

我正在尝试编写一个代码来删除字符串列表中的“the”、“this”等停止词

我写了这段代码:

let rec public stopword (a : string list, b :string list) =

    match [a.Head] with
        |["the"]|["this"] -> stopword (a.Tail, b)
        |[] -> b
        |_ ->  stopword (a.Tail, b@[a.Head])
我在交互界面上运行了这个:

stopword (["this";"is";"the"], []);;
我得到了这个错误:

这个表达式应该有类型字符串列表,但这里有类型“a*”b
匹配F#中的表达式功能非常强大,尽管一开始语法很混乱

您需要这样匹配列表:

let rec stopword a =
    match a with
    |"the"::t |"this"::t -> stopword t
    |h::t ->h::(stopword t)
    |[] -> []

实际错误是由于函数需要一个元组参数造成的。您必须使用以下命令调用函数:

let result = stopword (["this";"is";"the"], [])
编辑:由于原问题已更改,上述答案不再有效;实际函数中的逻辑错误是,最终得到的是一个元素列表,该列表的尾部为,结果是一个空列表。在下一次递归调用中,函数试图获取此空列表的开头时被阻塞

但是,该功能本身并没有正确实现,而且比必要的要复杂得多

let isNoStopword (word:string) =
    match word with
    | "the"|"this" -> false
    | _ -> true

let removeStopword (a : string list) =
    a |> List.filter(isNoStopword)

let test = removeStopword ["this";"is";"the"]

其他人提到了模式匹配在这种情况下的作用。实际上,您通常有一组要删除的停止词。而
when
保护让我们能够非常自然地匹配模式:

let rec removeStopwords (stopwords: Set<string>) = function
    | x::xs when Set.contains x stopwords -> removeStopwords stopwords xs 
    | x::xs -> x::(removeStopwords stopwords xs)
    | [] -> []
let rec removeStopwords(stopwords:Set)=函数
|x::xs当Set.contains x stopwords->removeStopwords stopwords xs时
|x::xs->x::(删除停止字xs)
| [] -> []
这个函数和@John的答案的问题在于它们不是尾部递归的。它们在由几个停止词组成的长列表中用完了堆栈。最好使用尾部递归的高阶函数:

let removeStopwords (stopwords: Set<string>) xs =
    xs |> List.filter (stopwords.Contains >> not)
let removeStopwords(stopwords:Set)xs=
xs |>List.filter(stopwords.Contains>>not)

非常感谢!!!!!!这个很有效率。我希望我能在几个月内写出这段代码:)谢谢你的实现。我用我的密码试过你的建议。它给出了以下错误:此表达式应具有类型字符串列表,但此处具有类型“a*”b@SiddharthaChatterjee-插入逗号的地方mistake@SiddharthaChatterjee我将函数改为只接受一个列表作为参数,而不是包含两个列表的元组(如John Palmer)。这两个代码块彼此独立。第一个是您应该如何调用函数,第二个是我的解决方案,包括“test”变量中的结果。注意:John Palmer的解决方案是您如何尝试解决问题的正确实现,虽然我打算在F#中说明,对于这个特定的问题,不需要递归函数,但我将使用一个单词列表来实现isNoStopword,以创建F#集或.NET哈希集。如果你真正的停止词列表很长,那么这两个词会给你带来更好的性能,因为集合成员的测试会很快。它还将打开从文本文件加载停止词的方法,而不是将它们包含在代码中。感谢您针对此问题公开了when-guard。很高兴听到各种解决问题的方法。