F# not returning at end of expression - .net-core
I have an issue where an F# program is not returning at the end of an expression and ends up executing the next expression below it.
The two expressions as they appear in the file:
let startCycle =
printfn "startCycle"
(0, "")
let blah =
printfn "blah"
(0, "")
And when startCycle is called it will print both messages to the console. Stepping through this with the debugger it goes from the first (0, "") to printfn "blah" and returns when it hits the second (0,""). I've checked the spacing several times, and Visual Studio appears to recognize these as two separate expressions.
Another weird thing is if I call startCycle multiple times it only prints on the first time through, every call after that results in nothing printed to the console unless I stop and restart the application. I'm using F# 4.7 with .NET Core 3. What am I missing?
EDIT:
Incase it helps, here is how startCycle is called:
let Run (cmdline: string) : (int * string) =
let cmodel = parseCmd cmdline
printfn "%A" cmodel
match cmodel.Command with
| "sendMsg4" -> Commands.sendMsg4 cmodel.Args
| "sendMsg7" -> Commands.sendMsg7 cmodel.Args
| "sendMsg8" -> Commands.sendMsg8 cmodel.Args
| "sendMsg10" -> Commands.sendMsg10 cmodel.Args
| "sendMsg16" -> Commands.sendMsg16 cmodel.Args
| "sendMsg19" -> Commands.sendMsg19 cmodel.Args
| "sendMsg22" -> Commands.sendMsg22 cmodel.Args
| "sendMsg29" -> Commands.sendMsg29 cmodel.Args
| "sendMixMessages1929" -> Commands.sendMixMessages1929
| "help" | "Help" -> Commands.help cmodel.Args
| "startCycle" -> Commands.startCycle
| "stopCycle" -> Commands.stopCycle
| "cycleStatus" -> Commands.cycleStatus
| "set" -> Commands.setStateValue cmodel.Args
| "show" -> Commands.show cmodel.Args
| "" -> (1, "")
| _ -> (-1, "Unknown Command")
startCycle and blah aren't written as functions, they're written as plain values. The let keyword in F# is used for both. Don't worry, this is a very common source of confusion for people new to the language.
To create a function that takes no parameters you need to put in a "dummy" parameter of unit, which is written as ():
let startCycle () =
printfn "startCycle"
(0, "")
This is then called like this: Commands.startCycle ()
Related
Pattern matching does not call function in F#
open System [<EntryPoint>] let main argv = match argv with | [| firstArg |] -> printfn "Your first arg is %s", firstArg | [| |] -> failwith "You didn't pass an argument" | _ -> failwith "You did something unusual" 0 // return an integer exit code I wrote this to process the first argument to my F# console application. If I didn't pass an argument it fails with an exception saying "You didn't pass an argument". If I passed at least two arguments, it fails with an exception "You did something unusual". But, when I pass exactly one argument, it tells nothing. Why does not printfn work here?
The reason it didn't print anything here is because you've added an extra comma after the printf. That means the signature is a string -> unit function and string tuple. If you remove the comma then it will work. A working solution would be [<EntryPoint>] let main argv = match argv with | [| firstArg |] -> printfn "Your first arg is %s" firstArg | [| |] -> failwith "You didn't pass an argument" | _ -> failwith "You did something unusual" 0 // return an integer exit code You might have seen a compiler warning before running this which said warning FS0020: The result of this expression has type '(string -> unit) * string' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'
F# Fabulous Xamarin: update view from code without user input
I'm new to Elmish.Xamarin and Xamarin itself. I'm trying to build an application, using this calculator example. Main difference is that in this example UI is updated upon user input, and update function is pure and just evaluates next state of model: let update msg model = match msg with | Clear -> Initial | Digit digit -> match model with | Initial | Error | Result _ -> Operand (double digit) | Operand op -> Operand (double (string op + string digit)) | OperandOperator (operand, operator) -> OperandOperatorOperand (operand, operator, double digit) | OperandOperatorOperand (op1, operator, op2) -> OperandOperatorOperand (op1, operator, double (string op2 + string digit)) | Operator operator -> match model with | Initial | Error -> model | Result operand // previously calculated result is now the first operand | Operand operand | OperandOperator (operand, _) -> OperandOperator(operand, operator) | OperandOperatorOperand _ -> calculate model msg | Equals -> calculate model msg I need a different scenario: user's input doesn't affect UI directly, instead I store user's messages and evaluate next state on schedule, so in my app's core I pass updateUI: gameState -> unit func: let gameAgentFn (mailboxNetwork: MailboxNetwork) updateUi gameState cmd = let timerAgent = timerAgent mailboxNetwork match gameState.gameFrame with | Frame field -> let gameState = Game.updateGameState gameState cmd timerAgent.Post Next updateUi gameState gameState Problem is I can't understand, what function to pass and how to build interaction with this design, since as far as I can see, it expects me to pass pure function to evaluate next state and the rest is being done underneath.
Pattern matching nested tuples in ocaml
I'm trying to recursively go through a nested list of files and folders. While I do that I want to print the names of files and folders I visit, but I am doing something very wrong. This is what I have: type 'a fileTree =¬ | File of 'a¬ | Folder of 'a * ('a fileTree list) let printFiles tree = let rec visit tree = function | [] -> print_string "Done" | File f :: t -> visit t | Folder (name, contents) :: t -> visit contents in visit tree Doing that I get Error: This expression has type 'a fileTree list -> unit but an expression was expected of type unit for line (File f :: t -> visit t). What am I doing wrong? EDIT 1 The code is now let printFiles tree = let rec visit = function | File file -> Printf.printf "file: %s\n" file | Folder (name, contents) -> Printf.printf "folder: %s\n" name; List.iter visit contents in List.iter visit tree But I still get this error for the last line: Error: This function has type ('a -> unit) -> 'a list -> unit It is applied to too many arguments; maybe you forgot a `;'
You forget parenthesis here: print_string "File " ^ f it is evaluated as (print_string "File ") ^ f, but what you're expecting is print_string ("File " ^ f) The same is with "Folder" case. Update In the updated example, you have a function of two arguments applied to one. I suppose, that instead of: let rec visit tree = function You want to write let rec visit = function which is equivalent to let rec visit tree = match tree with
The problem is that you've written visit as a function over lists but called it on a file tree. Let's change it to a function over trees and use List.iter to travese lists: let print_files tree = let rec visit = function | File file -> Printf.printf "file: %s\n" file | Folder (name, contents) -> Printf.printf "folder: %s\n" name; List.iter visit contents in visit tree
I solved it in the following way in the end: let writeFilesFromTree tree = let rec visit = function | [] -> print_string "-\n" | File f :: t -> Printf.printf "file: %s\n" f ; visit t | Folder (name, contents) :: t -> Printf.printf "name: %s\n" name ; visit contents ; visit t in visit tree;; It still doesn't feel like an optimal solution at all, and I have the feeling I am sabotaging tail recursion with the last two consecutive calls to visit.
Why am I getting an error in first case but not in second?
I started learning OCaml recently and came across the following problem: *Write a function last : 'a list -> 'a option that returns the last element of a list. * I tried the following code: # let rec last = function | [] -> None | _ :: t -> last t | [x] -> Some x;; I got the following response: Characters 65-68: Warning 11: this match case is unused. val last : 'a list -> 'a option = <fun> But the following code compiles without an error: # let rec last = function | [] -> None | [x] -> Some x | _ :: t -> last t;; giving the response val last : 'a list -> 'a option = <fun> So, my doubt is why just by changing the order I am getting the error? Any remarks and guidance will be highly appreciated. I asked this question on programmers.stackexchange As per suggestion I am asking on overflow.
in this line, | _ :: t -> last t what is t? it's a list!. That means it could either be a cons cell of (a :: a list), or it could be []. Since this case, along with the first, now match every possible list, the third case cannot be reached.
Erlang: choosing unique items from a list, using recursion
Given any list in Erlang, e.g.: L = [foo, bar, foo, buzz, foo]. How can I only show the unique items of that list, using a recursive function? I do not want to use an built-in function, like one of the lists functions (if it exists). In my example, where I want to get to would be a new list, such as SL = [bar, buzz]. My guess is that I would first sort the list, using a quick sort function, before applying a filter? Any suggestions would be helpful. The example is a variation of an exercise in chapter 3 of Cesarini's & Thompson's excellent "Erlang Programming" book.
I propose this one: unique(L) -> unique([],L). unique(R,[]) -> R; unique(R,[H|T]) -> case member_remove(H,T,[],true) of {false,Nt} -> unique(R,Nt); {true,Nt} -> unique([H|R],Nt) end. member_remove(_,[],Res,Bool) -> {Bool,Res}; member_remove(H,[H|T],Res,_) -> member_remove(H,T,Res,false); member_remove(H,[V|T],Res,Bool) -> member_remove(H,T,[V|Res],Bool). The member_remove function returns in one pass the remaining tail without all occurrences of the element being checked for duplicate and the test result.
I may do it this way :) get_unique(L) -> SortedL = lists:sort(L), get_unique(SortedL, []). get_unique([H | T], [H | Acc]) -> get_unique(T, [{dup, H} | Acc]); get_unique([H | T], [{dup, H} | Acc]) -> get_unique(T, [{dup, H} | Acc]); get_unique([H | T], [{dup, _} | Acc]) -> get_unique(T, [H | Acc]); get_unique([H | T], Acc) -> get_unique(T, [H | Acc]); get_unique([], [{dup, _} | Acc]) -> Acc; get_unique([], Acc) -> Acc.
I think idea might be: check if you already seen the head of list. If so, skip it and recursively check the tail. If not - add current head to results, to 'seen' and recursively check the tail. Most appropriate structure for checking if you already have seen the item is set. So,i'd propose following: remove_duplicates(L) -> remove_duplicates(L,[], sets:new()). remove_duplicates([],Result,_) -> Result; remove_duplicates([Head|Tail],Result, Seen) -> case sets:is_element(Head,Seen) of true -> remove_duplicates(Tail,Result,Seen); false -> remove_duplicates(Tail,[Head|Result], sets:add_element(Head,Seen)) end.
Use two accumulators. One to keep elements you have seen so far, one to hold the actual result. If you see the item for the first time (not in Seen list) prepend the item to both lists and recurse. If you have seen the item before, remove it from your result list (Acc) before recursing. -module(test). -export([uniques/1]). uniques(L) -> uniques(L, [], []). uniques([], _, Acc) -> lists:reverse(Acc); uniques([X | Rest], Seen, Acc) -> case lists:member(X, Seen) of true -> uniques(Rest, Seen, lists:delete(X, Acc)); false -> uniques(Rest, [X | Seen], [X | Acc]) end.
unique(List) -> Set = sets:from_list(List), sets:to_list(Set).
This solution only filters out duplicates from a list. probably requires building upon to make it do what you want. remove_duplicates(List)-> lists:reverse(removing(List,[])). removing([],This) -> This; removing([A|Tail],Acc) -> removing(delete_all(A,Tail),[A|Acc]). delete_all(Item, [Item | Rest_of_list]) -> delete_all(Item, Rest_of_list); delete_all(Item, [Another_item| Rest_of_list]) -> [Another_item | delete_all(Item, Rest_of_list)]; delete_all(_, []) -> []. EDIT Microsoft Windows [Version 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\Windows\System32>erl Eshell V5.9 (abort with ^G) 1> List = [1,2,3,4,a,b,e,r,a,b,v,3,2,1,g,{red,green},d,2,5,6,1,4,6,5,{red,green}]. [1,2,3,4,a,b,e,r,a,b,v,3,2,1,g, {red,green}, d,2,5,6,1,4,6,5, {red,green}] 2> remove_duplicates(List). [1,2,3,4,a,b,e,r,v,g,{red,green},d,5,6] 3>
Try the following code -module(util). -export([unique_list/1]). unique_list([]) -> []; unique_list(L) -> unique_list(L, []). % Base Case unique_list([], Acc) -> lists:reverse(Acc); % Recursive Part unique_list([H|T], Acc) -> case lists:any(fun(X) -> X == H end, T) of true -> unique_list(lists:delete(H,T), Acc); false -> unique_list(T, [H|Acc]) end.
unique(L) -> sets:to_list(sets:from_list(L)).
The simplest way would be to use a function with an "accumulator" that keeps track of what elements you already have. So you'd write a function like % unique_acc(Accumulator, List_to_take_from). You can still have a clean function, by not exporting the accumulator version, and instead exporting its caller: -module(uniqueness). -export([unique/1]). unique(List) -> unique_acc([], List). If the list to take from is empty, you're done: unique_acc(Accumulator, []) -> Accumulator; And if it's not: unique_acc(Accumulator, [X|Xs]) -> case lists:member(X, Accumulator) of true -> unique_acc(Accumulator, Xs); false -> unique_acc([X|Accumulator], Xs) end. 2 things to note: -- This does use a list BIF -- lists:member/2. You can easily write this yourself, though. -- The order of the elements are reversed, from original list to result. If you don't like this, you can define unique/1 as lists:reverse(unique_acc([], List)). Or even better, write a reverse function yourself! (It's easy).