我正在尝试在F#中编写一个模块,它将从列表中删除每个第3个元素,并返回一个没有这些元素的新列表。
例如
let input = [ 1 .. 15 ]
printfn "List with elements eliminated: %A" (Program1.remove input)
可以提供此输出
List with elements eliminated: [1; 2; 4; 5; 7; 8; 10; 11; 13; 14]
到目前为止我尝试了什么
module Program1 =
open System
let remove list1=
let collectList = List.iteri (fun i x -> if i%3 <> 0 then x) list1
collectList
[<EntryPoint>]
let main argv =
let list = [ 1; 2; 3]
printfn "new List is %A" (Program1.remove list )
0
现在我收到了一个错误,我整日都在尝试解决它。 提前谢谢
答案 0 :(得分:1)
对于此错误:
error FS0001: Type mismatch. Expecting a
'unit list'
but given a
'int list'
The type 'unit' does not match the type 'int'
问题来自第if i%3 <> 0 then x
行。它是一个没有else子句的if-expression,它必须具有unit
类型,类型推断导致x
类型为unit
。有关F#条件的更多详细信息,请阅读https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/conditional-expressions-if-then-else。
编辑:此外,List.iteri
没有执行您要执行的操作,因为List.iteri
未返回列表,它返回unit
。您需要List.map
,List.filter
,List.choose
,List.foldBack
等功能来解决您的问题。
阅读此帖子中接受的答案,以了解如何解决此问题(您需要进行少量修改):Getting every nth Element of a Sequence
使用List.foldBack
构建结果列表还有一种更简单的方法。
答案 1 :(得分:0)
我不确定您是否尝试过滤每个第三个值或每个可分为3的值。
如果它的第一种情况比一种功能性方法可能是这样的
//safe take and skip fn (no exceptions)
let take x xs = if List.length xs >= x then List.take x xs else []
let skip x xs = if List.length xs >= x then List.skip x xs else []
let rec remove x xs =
//effectively this drops every xnt element
let head = take (x - 1) xs
let tail = skip x xs
match tail with
| [] -> head
| _ -> List.append head (remove x tail)
let x = ["One";"Two";"Three";"Four";"Five";"Six";"Seven";"Eight";"Nine";"Ten"]
remove 3 x
然而,这是相当重的;-)
所以更好的方法可能就像你几乎找到的那样
let x = ["One";"Two";"Three";"Four";"Five";"Six";"Seven";"Eight";"Nine";"Ten"]
let indices = [1 .. List.length x]
List.zip indices x
|> List.filter (fun (x,_) -> x % 3 <> 0)