Is there a less verbose way to unwrap maybe values in Elm - functional-programming

I've been running into a frequent issue in elm where I have a function that depends on multiple maybe values being Just. Is there a less verbose way to write this code:
commandIf apples bananas oranges =
case apples of
Just apples_ ->
case bananas of
Just bananas_ ->
case oranges of
Just oranges_ ->
someCommand apples_ bananas_ oranges_
Nothing ->
Cmd.none
Nothing ->
Cmd.none
Nothing ->
Cmd.none

If you need all three values at the same time you can match them together as a tuple and leave all other combinations (when one of them or several are Nothing) to the fallback case:
commandIf apples bananas oranges =
case (apples, bananas, oranges) of
(Just apples_, Just bananas_, Just oranges_) ->
someCommand apples_ bananas_ oranges_
_ ->
Cmd.none

#laughedelic's answer is very good. Just wanted to offer some alternative and more generic solutions too, since verbose Maybe unwrapping is an issue I also ran into when I started out in Elm.
If you have a fixed number of Maybe values, you can use map2, map3 etc to do what you want (docs here):
commandIf apples bananas oranges =
Maybe.map3 someCommand apples bananas oranges
|> Maybe.withDefault Cmd.none
Here, someCommand is your functions that takes 3 arguments, and returns a some command.
Maybe.map3 applies this function only if all 3 variables are Just x, and wraps it in one Maybe type. So the result is Just (someCommand apples bananas oranges) if all 3 have a value. Otherwise, the function returns Nothing.
This result is then "piped" into Maybe.withDefault. Which returns a Cmd.none if the input is Nothing, and otherwise returns the value (your command), without the Just.
If you would have a list of Maybe values of unknown length, you could do something this:
keepOnlyJusts : List (Maybe a) -> List a
keepOnlyJusts listOfMaybes =
listOfMaybes
|> List.filterMap identity
newList = keepOnlyJusts [ Just 1, Nothing, Just 3 ] -- == [1,3]
where the result is a list (could be empty) where only the values are kept.

Maybe.map3 solves your particular case, but this answer is about the general pattern of chaining maybe values using Maybe.andThen.
commandIf a_ b_ c_ =
a_ |> Maybe.andThen (\a ->
b_ |> Maybe.andThen (\b ->
c_ |> Maybe.andThen (Just << someCommand a b)))
|> Maybe.withDefault Cmd.none

Related

## and |> operators precedence in OCaml

I'm trying to understand 2 OCaml operators: ## and |>
I understand that x |> f is just f(x), but why it exists? I cannot see why. The same for ##, which as I unferstood, is just normal function application
For example:
match get_ipv4_hlen_version buf |> version with
| 0x40 -> Ok buf
| n -> Error (Printf.sprintf "IPv4 presented with a packet that claims a different IP version: %x" n)
why not write just get_ipv4_hlen_version version buf?
What about
let options_len = nearest_4 ## Cstruct.len t.options
why not let options_len = nearest_4 Cstruct.len t.options
?
I suppose it has to do with precedence, I recall some of these things from Haskell but I don't know Haskell I just read somewhere.
How do I know the precedence of things?
if more context is needed, these 2 codes came from https://github.com/mirage/mirage-tcpip/blob/master/src/ipv4/ipv4_packet.ml
The notational value of |> only appears if you have several nested function applications. Many people find this:
x |> f a |> g b c |> h d
easier to read than this:
h d (g b c (f a x))
because it's no longer necessary to match up the parentheses mentally, and because the operations are applied in left-to-right order (which is arguably natural for readers of English and other left-to-right languages).
If you are familiar with Unix command lines, it might help to think of the |> operator as similar to the Unix pipe operator |.
A lower-precedence function application operator like ## also helps avoid parentheses (and mental matching thereof). Many people find this:
f x ## g a b ## h c d
easier to read than this:
f x ((g a b) (h c d))
Your example for ## is wrong. This
let options_len = nearest_4 ## Cstruct.len t.options
is equivalent to this:
let options_len = nearest_4 (Cstruct.len t.options)
and is not equivalent to what you wrote.
The precedence of an operator is determined by its first character. This, in turn, is defined by the table in Section 7.7.1 of the OCaml manual.
(Granted, you need to read very carefully the text just before the table to see the rule for precedence.)
Update
Full disclosure: I never use |> or ## in my own code. I have no problem with a few parentheses, and I generally use let to break a big expression down into smaller pieces.
The |> operator is very convenient. It is the equivalent of the pipe in the shell. It allows you to write code like this:
let make_string n =
Array.init n float_of_int
|> Array.map (fun x -> x -. 0.5 *. (float_of_int (n-1)))
|> Array.map (fun x -> Printf.sprintf "-- %10.6f --" x)
|> Array.to_list
|> String.concat "\n"
in
make_string 5
(* Output:
-- -2.000000 --
-- -1.000000 --
-- 0.000000 --
-- 1.000000 --
-- 2.000000 --
*)
In this example, each line starting with a |> takes the output of the previous transformation, so we can see the flow of data transformations, like in Bash when we write something like
ls | grep txt | sort | uniq
The ## operator is the "backwards pipe". It allows to remove parenthesis that would make the code less readable. For example, take the case where we want to make a chain of matrix products like C = A.B.C.D. You want the code to be consistent with the mathematical formula, so you want to write it in the same order. If mm A B makes the matrix multiplication of A and B, then we can write
let mat_C =
mm mat_A ## mm mat_B ## mm mat_C mat_D
instead of
let mat_C =
mm mat_A (mm mat_B (mm mat_C mat_D))

F# - Create a Recursive Discriminated Union at Runtime

I am trying to write a simple interpreter to control a Turtle using F#.
I have created the following recursive union type to represent the few commands that the Turtle will accept. The code will be represented by a "Command list" that shouldn't be too hard to execute with a simple recursive function.
type Command =
| Repeat of amount * Command list
| Forward of amount
| Turn of direction * amount
I want to make this interpreter white space delineated so the source could look as follows.
Forward 75
Repeat 4
Forward 10
Turn Right 50
Repeat 6
Forward 20
Turn Right 60
Repeat 8
Forward 15
Turn Left 30
Turn Right 10
Forward 25
I then have this function to separate everything into an int*string list based on the indentation level. So Repeat 4 would become (0, "Repeat 4"), Forward 10 would be (1, "Forward 10"), and Turn Left 30 would be (3, "Turn Left 30").
/// Creates indentation chart for generating a syntax tree by cycling
/// through a list of strings generated
/// by string.Split and counting the empty strings before each non-empty
//// string.
let indent strs =
let rec inner strs search cmds indent temp =
match strs, search with
| [], _ -> (indent,temp)::cmds
| ""::tail, Cmd -> inner tail Indent ((indent,temp)::cmds) 0 "" //
Newline started -> push cached counter and command string
| ""::tail, Indent -> inner tail Indent cmds (indent+1) temp // Next
level of indent -> increment indent counter
| h::tail, Cmd -> inner tail Cmd cmds indent (temp + " " + h)
| h::tail, Indent -> inner tail Cmd cmds indent (temp + h)
| h::tail, Start -> inner tail Cmd cmds indent (temp + h)
inner strs Start [] 0 "" |> List.rev
let splitIndent (text:string) = text.Trim().Split() |> Array.toList |>
indent
Now this is where I am stuck. I have the list of commands with their indentation levels, but I do not know how to dynamically create a recursive discriminated union. I know how to hardcode it in. It looks something like this,
let tree = [
Forward 75
Repeat (4, [
Forward 10
Turn (Right, 50)
Repeat (6, [
Forward 20
Turn (Right, 60)
Repeat (8, [
Forward 15
Turn (Left, 30)
])])
Turn (Right, 10)])
Forward 25]
but I do not know how to generate something like this based on different input strings.
I have read many StackOverflow posts related to trees, discriminated unions, and creating recursive types like this dynamically but I have not found anything that fits my needs. I have tried modifying the few examples that I have found and the closest I found was an answer by Tomas Petricek at F# transform list to a tree. Plugging in the union cases and the pattern matching for them to get this to work got me a lot closer, but it left off a lot of commands and duplicated some of the others.
This is the best that I have come up with so far, but it does not get all of the commands.
/// Takes the indent,command pairs list and produces a list of commands.
/// Some of these are nested in a tree structure based on their indent.
let buildProgram (diagram:(int*string) list) : Command list =
let rec collect indx lis commands =
match lis with
| [] -> commands
| x::xs ->
match fst x with
| i when i = indx ->
match split (snd x) with
| "Forward"::NUM n::tail -> collect i xs commands#[Forward
n]
| "Turn"::ARG a::NUM n::tail -> collect i xs
commands#[Turn(a,n)]
| "Repeat"::NUM n::tail -> commands#([(Repeat (n, (collect
(i+1) xs [])))] |> List.rev)
| i when i < indx ->
match split (snd x) with
| "Forward"::NUM n::tail -> collect (i-1) xs
commands#[Forward n]
| "Turn"::ARG a::NUM n::tail -> collect (i-1) xs
commands#[Turn(a,n)]
| "Repeat"::NUM n::tail -> commands#([(Repeat (n, (collect
(i-1) xs [])))] |> List.rev)
collect 0 diagram [] |> List.rev
How do you create a recursive discriminated union at runtime based on different inputs?
What you're trying to do there is to write a parser for your indentation-based syntax that would produce values of type Command.
You can certainly roll one by hand, but the general advice would be to use a parser combinator library such as FParsec. FParsec does have a steep learning curve, but it's "the way to go" for writing parsers in F#.
You will find this article particularly helpful if you decide to go with that - Parsing indentation based syntax with FParsec.

Regarding OCaml Pattern Matching Syntax

I am following this OCaml tutorial.
They provided the two functions below and said that they are equivalent.
let string_of_int x = match x with
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| _ -> "many"
let string_of_int2 = function
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| _ -> "many"
My query is regarding the syntax of the above functions.
I wrote the same function but instead of | 0 -> I simply did 0 -> and the function still works in the same way. Is there any particular reason that the tutorial added the extra | in their function?
In the second function what is the use of the function keyword and why was this keyword absent in the first function?
Some people think it looks nicer and more organized, and it allows you to change the order of cases using cut & paste without having to worry about which one didn't have the |.
The function syntax is an abbreviation: function [CASES] is the same as fun x -> match x with [CASES]. There is a subtle difference, which is with function it is not possible to shadow another variable by the name of the parameter.
let string_of_int x = [EXP] is itself an abbreviation for let string_of_int = fun x -> [EXP].
So, to a close approximation, the "canonical" syntax uses fun and match, everything else is sugar. If you apply these two expansions to the two versions of the function, you will see that the same code results (modulo alpha-equivalence, of course :) ).

Set Intersection with Tail Recursion

I am trying to produce the solution for an intersection of two sets using tail recursion and an empty list [] as an accu:
let rec setintersect list list =
let rec setintersect2 a b c =
match a with
| [] -> (match b with [] -> (setsimplify c) | h::t -> (setsimplify c))
| h1::t1 -> (match b with [] -> (setsimplify c) |h2::t2 -> (if (elementof h1 b) then (setintersect2 t1 b (c#[h1])) else (setintersect2 t1 b c))) in
setintersect2 list list [];;
Elementof takes takes "an int and a list" and is correctly working to give true if x is an element of the list, false otherwise..
Here is the problem:
# setintersect [5;2;1] [2;6;9];;
- : int list = [2; 6; 9]
and it should give [2].
What am I doing wrong?
I feel like there's something really simple that I am misunderstanding!
Edit:
Thanks for the responses so far.
setsimplify just removes the duplicates.
so [2,2,3,5,6,6] becomes [2,3,5,6]. Tested and made sure it is working properly.
I am not supposed to use anything from the List library either. Also, I must use "tail recursion" with the accumulator being a list that I build as I go.
Here is the thought:
Check the head element in list1, IF it exists in list2, THEN recurse with the "tail of list1, list2, and list c with that element added to it". ELSE, then recurse with "tail of list1, list2 and list c(as it is)".
end conditions are either list1 or list2 are empty or both together are empty, return list c (as it is).
let rec setintersect list list = is wrong: the two arguments should be named differently (you should of course update the call to setintersect2 accordingly), otherwise the second will shadow the first. I would have thought that OCaml would have at least warned you about this fact, but it appears that it is not the case.
Apart from that, the code seems to do the trick. There are a couple of things that could be improved though:
setintersect itself is not recursive (only setintersect2 is), you thus don't need the rec
you should find a different name for the argument of setintersect2. In particular, it is not obvious which is the accumulator (acc or accu will be understood by most OCaml programmers in these circumstances).
c#[h1] is inefficient: you will traverse c completely each time you append an element. It's better to do h1::c and reverse the result at the end
As a bonus point, if you append element at the beginning of c, and assume that a is ordered, you don't have to call setsimplify at the end of the call: just check whether c is empty, and if this is not the case, append h1 only if it is not equal to the head of c.
First, You didn't list out your setsimplify function.
To write an ocaml function, try to split it first, and then combine if possible.
To solve this task, you just go through all elements in l1, and for every element, you check whether it is in l2 or not, right?
So definitely you need a function to check whether an element is in a list or not, right?
let make one:
let rec mem x = function
| [] -> false
| hd::tl -> hd = x || mem x tl
Then you can do your intersection:
let rec inter l1 l2 =
match l1 with
| [] -> []
| hd::tl -> if mem hd l2 then hd::(inter tl l2) else inter tl l2
Note that the above function is not tail-recursive, I guess you can change it to tail-recursive as an excise.
If you use std library, then it is simple:
let intersection l1 l2 = List.filter (fun x -> List.mem x l2) l1

Ocaml Pattern Matching Qualms

I'm having a bit of a problem with regards to pattern matching in Ocaml.
Basically, I need to write a function named reversed that accepts a list and checks whether or not it is in reversed order.
So far:
let rec reversed (x:int list):bool =
match x with
| [] -> true
| y::z::tl -> if y < z then false else reversed tl;
| y::[] -> true;;
It works! (to my surprise actually :P) But there is a flaw I can see, that is if there is no more tl, it would not match. Testing this returns true:
reversed [5;4;3;1;2];;
Which is perfectly understandable since there's no more tail and it simply matches to y::[]
How would I fix this?
PS: This is my first day with Ocaml. Sorry if the question is very easy :D
PPS: I am purposely only using Core. (no modules)
PPPS: I understand the case if I'm doing something fundamentally wrong, please do point it out.
The problem in your function is here :
| y::z::tl -> if y < z then false else reversed tl;
Let's look at your list : [5;4;3;1;2]
It is decomposed this way :
| 5::4::[3;1;2]
And you compare 5 and 4, and then call reverted with [3;2;1]. Wich means that the comparaison between 4 and 3 is not done ! (you can try with a list like [5;4;99;98;97], it is the unexpected result that you have).
What you should do is test on z, and then call reverted with the rest of the list. But if you try something like :
| y::z::_ -> if y < z then false else reversed z;
The compilers yells at you, because z is an int (and not an int list anymore). To solve this, you can "reconstruct" the list by adding z in front of tl :
| y::z::tl -> if y < z then false else reversed (z::tl)
Or name the list after y (which contains z) while still extracting z :
| y::(z::_ as tl) -> if y < z then false else reversed tl
As for your guess about the problem, I understand your logic but actually it does not work that way.
[] can be "named" in your decomposition, just as if it was a regular node.
Look at this example, a (bad) function who tests if the end of the list is reached :
let is_end l = match l with
| a -> false
| [] -> true;;
If you try to put that in your interpreter, you should get the following message :
Warning 11: this match case is unused.
That's because [] is already caught in the first match case. You can try with is_end [], it returns false.
The correct way to handle this is how you did it in your code :
let is_end l = match l with
| x::_ -> false
| [] -> true;;
Your program logic is wrong. You want to check if the list is reversed (decreasing?). But your program fails on input
[5;3;4;2;1]
telling you that it is reversed/decreasing. This is because you drop the 3 too early. Your middle clause should be:
| y::z::tl -> if y < z then false else reversed (z::tl);
You should use | y::z::tl -> if y < z then false else reversed (z::tl).
if y > z, you shouldn't drop z from the next round of list because z has not been compared to the next item yet.
Also you don't need ; in that line.
the correct code is
let rec reversed = function
| [] -> true
| hd::[] -> true
| hd1::hd2::tl ->
if hd1 < hd2 then false
else reversed (hd2::tl)
Here is another way to write it using some other concepts like pattern guards and wild cards:
let rec reversed = function
| [] | [_] -> true
| hd1::hd2::_ when hd1 < hd2 -> false
| _::tl -> reversed tl;;
This way there is one case for true, one for false, and one recursive.

Resources