Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 在F中继续使用相同的列表#_F#_Functional Programming - Fatal编程技术网

F# 在F中继续使用相同的列表#

F# 在F中继续使用相同的列表#,f#,functional-programming,F#,Functional Programming,我正在开发一个F#程序,它读取文件并根据每行的事件执行特定的操作 例如,如果行中的第一个单词是create,我向列表中添加一个元素;如果是delete,我从列表中删除一个元素;如果modify,我修改列表中的值 现在我正在使用map,它只对每一行应用processEventType函数,但我需要一种方法来继续处理相同的列表 let processEventType (words:string[]) myList = match words with | [| event; va

我正在开发一个F#程序,它读取文件并根据每行的事件执行特定的操作

例如,如果行中的第一个单词是create,我向列表中添加一个元素;如果是delete,我从列表中删除一个元素;如果modify,我修改列表中的值

现在我正在使用map,它只对每一行应用processEventType函数,但我需要一种方法来继续处理相同的列表

let processEventType (words:string[]) myList =
    match words with 
    | [| event; var1; var2; var3 |] when event = "create" -> Map.add var2 var3 myList
    | [| event; var1; var2; |] when event = "delete" -> Map.remove "2" myList
    | _ -> failwith "Error processing event"


 let test (lines: list<string>) =
    List.map (fun line -> (processEventType(splitLine line) myList)) lines
let processEventType(words:string[])myList=
用词搭配
|[| event;var1;var2;var3 |]当event=“create”->Map.add var2 var3 myList
|[| event;var1;var2;|]当event=“delete”->Map.remove“2”myList时
|->failwith“错误处理事件”
let测试(行:列表)=
List.map(有趣的行->(processEventType(拆分行)myList))行

非常感谢您的帮助,因为我是函数式编程和F#的新手。

如果我正确理解了您的问题,那就是
processEventType
不允许您反复使用相同的列表。如果将事件应用于列表,则该事件的结果列表不会用于下一个事件

因为你是新手,所以我无法查看你的历史来确定你的知识库,所以我不能给你相关想法的参考和指针

基本上,对于
processEventType
,您需要返回列表(
newList
),作为每个模式匹配的最终语句

// Signature of processEventType 
val processEventType : string * string list -> theList:string list -> string list
然后在调用
processEventType
的函数中获取该结果,并使用递归函数将其传递回
processEventType

    let rec processEvents commands theList =
        match commands with
        | (command::t) ->
            let newList = processEventType command theList
            processEvents t newList
        | [] -> theList
对于这个答案,当其他人正确使用类似于List.map的函数时,我将使用
let rec
;这只是个人的喜好,第一次剪。我还可以使用
|>
对它进行重构,但如果您想插入
printfn
以查看发生了什么,或者使用调试器,请不要对它进行分解

代码比您拥有的要大得多,因为使用
F#immutable list
允许我按说明传递结果,因此我对输入进行了更多的处理,并添加了一些函数来处理列表中的数据

namespace Workspace

module main =

    [<EntryPoint>]
    let main argv = 

        let theList = []
        let input : string  = 
            "add 1 2 3 4" + System.Environment.NewLine +
            "delete 1 2" + System.Environment.NewLine +
            "add 1" + System.Environment.NewLine +
            "delete 4 2" + System.Environment.NewLine + 
            "modify 1 5" + System.Environment.NewLine

        let lines = input.Split([| '\n';'\r' |])
        let lines = List.ofArray lines
        let lines = List.filter  (fun (x : string) -> x.Length > 0) lines
        let commands = List.map(fun (line:string) -> line.Split([| ' ' |])) lines
        let commands = List.map(List.ofArray) commands
        let convertCommand (input : string list) : (string * string list) =
            let command = List.head input
            let values = List.tail input
            (command,values)
        let commands = List.map(convertCommand) commands
        let rec merge master items = 
            match master,items with
            | [],l | l,[] -> l
            | x::xs', y::ys' -> 
                if x = y then x :: (merge xs' ys')
                elif x < y then x :: (merge xs' items)
                else y :: (merge master ys')
        let deleteItems master items =
            let deleteItem master item =
                let rec deleteItem master item acc =
                    match master with
                    | (h::t) when h <> item ->
                        let acc = h :: acc
                        deleteItem t item acc
                    | (h::t) ->
                        deleteItem t item acc
                    | [] -> List.rev acc
                deleteItem master item []
            let rec deleteItemsInner master items =
                match items with
                | (item::t) ->
                    let master = deleteItem master item
                    deleteItemsInner master t
                | [] -> master
            deleteItemsInner master items     
        let modifyItems master v1 v2 =
            let rec modifyInner master v1 v2 acc =
                match master with
                | (h::t) when h = v1 ->
                    let acc = v2 :: acc
                    modifyInner t v1 v2 acc
                | (h::t) ->
                    let acc = h :: acc
                    modifyInner t v1 v2 acc
                | [] -> List.rev acc
            modifyInner master v1 v2 []
        let processEventType (event : (string * string list)) (theList : string list) : string list =
            let (command,eventValues) = event
            match command with
            | "add" -> 
                printfn "Adding: %A" eventValues
                let newList = merge theList eventValues
                printfn "result: %A" newList
                newList
            | "delete" ->
                printfn "Deleting: %A" eventValues
                let newList = deleteItems theList eventValues
                printfn "result: %A" newList
                newList 
            | "modify" ->
                match eventValues with
                | v1::v2::[] -> 
                    printfn "Modifying: %A %A" v1 v2
                    let newList = modifyItems theList v1 v2
                    printfn "result: %A" newList
                    newList
                | _ -> failwith "Error with modify parameters"
            | _ -> failwith "Error processing event"


        let rec processEvents commands theList =
            match commands with
            | (command::t) ->
                let newList = processEventType command theList
                processEvents t newList
            | [] -> theList

        let newList = processEvents commands theList

        printfn "theList: %A" newList

        printf "Press any key to exit: "
        System.Console.ReadKey() |> ignore
        printfn ""

        0 // return an integer exit code

这里的问题到底是什么?如果我理解正确的话,他的问题是processEventType没有返回一个可以重新传递以供重用的列表。可能您正在寻找初始映射状态为
map.empty
list.map
。但我猜得很疯狂,因为我不知道很多标识符应该是什么意思。将此问题重新表述为一个或多个简单的问题可能会有用,在这些问题中,输入、所用值的含义和所需结果都很清楚。@Vandroy
List.fold
正是我想要的,谢谢!非常感谢你!我没想到会有这样的回答。我决定使用
List.fold
。但这就是我的问题的意思,如何递归地保持processEventType返回的列表
Adding: ["1"; "2"; "3"; "4"]
result: ["1"; "2"; "3"; "4"]
Deleting: ["1"; "2"]
result: ["3"; "4"]
Adding: ["1"]
result: ["1"; "3"; "4"]
Deleting: ["4"; "2"]
result: ["1"; "3"]
Modifying: "1" "5"
result: ["5"; "3"]
theList: ["5"; "3"]
Press any key to exit: