I have conditional expressions <e1?e2:e3>. If e1 evaluates to zero, then the whole expression evaluates to the value of e2, and if e1 evaluates to anything else, the whole expression has the value of e3. Could someone help point me in the right direction of how to add conditional expressions?
2 remarks:
0 and not 0 are not the usual values used for boolean expressions, in erlang they are the atoms true and false.
Although it is possible to define a macro with parameters, it is not very usual to share those macros, via include files, between many modules. The exceptions are the record definitions within the scope of an application or a library.
I think that the 2 common ways to code this choice are either directly in the code:
Result = case E1 of
0 -> E2;
_ -> E3
end,
either define a local function:
choose(0,E2,_) -> E2;
choose(_,_,E3) -> E3.
...
Result = choose(E1,E2,E3),
of course (despite of my second remark that implies that you will repeat the macro definition again and again) you can code the first one with a macro:
-define(CHOOSE(E1,E2,E3),case E1 of 0 -> E2; _ -> E3 end).
...
Result = ?CHOOSE(E1,E2,E3),
see also this topic: How to write “a==b ? X : Y” in Erlang?
case E1 =:= 0 of
true -> E2;
_ -> E3
end
if E1 is expression allowed in guard it will generate exactly same bytecode as
if E1 =:= 0 -> E2;
true -> E3
end
You could make it as macro:
-define(IF(E1, E2, E3), case E1 =:= 0 of
true -> E2;
_ -> E3
end).
Related
I currently have this f# function
let collatz' n =
match n with
| n when n <= 0 -> failwith "collatz' :n is zero or less"
| n when even n = true -> n / 2
| n when even n = false -> 3 * n + 1
Any tips for solving the following problem in F#?
As said in the comments, you need to give a bit more information for any really specific advice, but based on what you have I'll add the following.
The function you have declared satisfies the definition of the Collatz function i.e. even numbers -> n/2 ,and
odd number -> 3n + 1.
So really you only need applyN, let's break it down into its pieces
( `a -> `a) -> `a -> int -> `a list
applyN f n N
That definition is showing you exactly what the function expects.
lets look at f through to N
f -> a function that takes some value of type 'a (in your case likely int) and produces a new value of type 'a.
This corresponds to the function you have already written collatz`
n -> is your seed value. I don't think elaboration is required.
N -> This looks like a maximum amount of steps to go through. In the example posted, if N was larger, you would see a loop [ 1 ;4; 2; 1; 4... ]
and if it was smaller it would stop sooner.
So that is what the function takes and need to do, so how can we achieve this?
I would suggest making use of scan.
The scan function is much like fold, but it returns each interim state in a list.
Another option would be making use of Seq.unfold and then only taking the first few values.
Now, I could continue and give some source code, but I think you should try yourself for now.
I am trying to parse a record from a lists of lists (continuing from this question).
Here's my record
data Record = Record Text Text Text Text Text Text Text Text Text deriving (Show, Generic)
This syntax works:
parseRecords :: [[Text]] -> [Record]
parseRecords = map (\[f1,f2,f3,f4,f5,f6,f7,f8,f9,_] -> Record f1 f2 f3 f4 f5 f6 f7 f8 f9)
This syntax checks, but has me fixed at 10 parameters. I would rather be able to have more than that and ignore the ones greater by pattern matching them into a [_] list I will not pass along. I tried the following:
parseRecords = map (\f1:f2:f3:f4:f5:f6:f7:f8:f9:[_] -> Record f1 f2 f3 f4 f5 f6 f7 f8 f9)
This, however, fails with:
Parse error (line 27, column 24): parse error on input ‘:’
I could have sworn I saw this kind of pattern matching used in lambdas before. What am I missing that my colon operators are a parse error? It is hard to interrogate what's going wrong.
Thanks!
Just like you need parentheses around patterns in function bindings,
f (x:xs) = ...
you need parentheses around patterns in lambdas:
parseRecords = map (\ (f1:f2:f3:f4:f5:f6:f7:f8:f9:_) -> Record f1 f2 f3 f4 f5 f6 f7 f8 f9)
-------pattern----------------
------------------lambda function--------------------------------------
Sometimes parentheses can be omitted, but not always. The list patterns are:
[] matches []
(x:xs) matches [x, ...] so that (x:xs) == [x] ++ xs
(x:y:xs) matches [x, y, ...] so that (x:y:xs) == [x] ++ (y:xs)
== [x,y] ++ xs
..... and so on ......
This is because : associates to the right, so (x:y:xs) is actually (x:(y:xs)).
Lastly, _ is a wildcard. It is like a variable pattern like x or y or xs, but without a name. Each _ is different from another, as if it was named with a unique, though missing, name.
I'm trying to write some function that handle errors by returning double options instead of doubles. Many of these functions call eachother, and so take double options as inputs to output other double options. The problem is, I can't do with double options what I can do with doubles--something simple like add them using '+'.
For example, a function that divides two doubles, and returns a double option with none for divide by zero error. Then another function calls the first function and adds another double option to it.
Please tell me if there is a way to do this, or if I have completely misunderstood the meaning of F# option types.
This is called lifting - you can write function to lift another function over two options:
let liftOpt f o1 o2 =
match (o1, o2) with
| (Some(v1), Some(v2)) -> Some(f v1 v2)
| _ -> None
then you can supply the function to apply e.g.:
let inline addOpt o1 o2 = liftOpt (+) o1 o2
liftA2 as mentioned above will provide a general way to 'lift' any function that works on the double arguments to a function that can work on the double option arguments.
However, in your case, you may have to write special functions yourself to handle the edge cases you mention
let (<+>) a b =
match (a, b) with
| (Some x, Some y) -> Some (x + y)
| (Some x, None) -> Some (x)
| (None, Some x) -> Some (x)
| (None, None) -> None
Note that liftA2 will not put the cases where you want to add None to Some(x) in automatically.
The liftA2 method for divide also needs some special handling, but its structure is generally what we would write ourselves
let (</>) a b =
match (a, b) with
| (Some x, Some y) when y <> 0.0d -> Some (x/y)
| _ -> None
You can use these functions like
Some(2.0) <+> Some(3.0) // will give Some(5.0)
Some(1.0) </> Some(0.0) // will give None
Also, strictly speaking, lift is defined as a "higher order function" - something that takes a function and returns another function.
So it would look something like this:
let liftOpt2 f =
(function a b ->
match (a, b) with
| (Some (a), Some (b)) -> f a b |> Some
| _ -> None)
In the end, I realized what I was really looking for was the Option.get function, which simply takes a 'a option and returns an 'a. That way, I can pattern match, and return the values I want.
In this case you might want to consider Nullables over Options, for two reasons:
Nullables are value types, while Options are reference types. If you have large collections of these doubles, using Nullables will keep the numbers on the stack instead of putting them on the heap, potentially improving your performance.
Microsoft provides a bunch of built-in Nullable Operators that do let you directly perform math on nullables, exactly as you're trying to do with options.
I'm doing a few exercises from HtDP (How to Design Programs) and I am kind of stuck on the Boolean comparison question. It goes like this.
(define b1 true)
(define b2 false)
Write an expression that computes whether b1 is false and b2 is true. If false produce No and vice versa.
Right now this is all I have come up with:
(and b1 true) => true
(Shameless. I know but I am new at this and I am really slow to catch on)
Any help you could give me would be match appreciated.
Thanks
It's pretty straightforward to translate the question into code. As a first approach, let's copy the question verbatim in pseudocode:
(b1 == false) AND (b2 == true)
Now, how would you write the above in Scheme? remember, Scheme uses prefix notation
(<???> (<???> b1 false) (<???> b2 true))
With a bit more of practice, the same code can be written more compactly like this (again, first in pseudocode):
NOT b1 AND b2
Which should be simple enough to write in Scheme:
(<???> (<???> b1) b2)
Not sure if this is the HtDP way of writing expressions, but you can write a simple truth table and find the boolean expression:
b1 | b2 | Y
0 | 0 | 0
0 | 1 | 1
1 | 0 | 0
1 | 1 | 0
hence Y = (NOT b1) AND b2 => TRUE
I have the following function that takes a number like 5 and creates a list of all the numbers from 1 to that number so create(5). returns [1,2,3,4,5].
I have over used guards I think and was wondering if there is a better way to write the following:
create(N) ->
create(1, N).
create(N,M) when N =:= M ->
[N];
create(N,M) when N < M ->
[N] ++ create(N + 1, M).
The guard for N < M can be useful. In general, you don't need a guard for equality; you can use pattern-matching.
create(N) -> create(1, N).
create(M, M) -> [M];
create(N, M) when N < M -> [N | create(N + 1, M)].
You also generally want to write functions so they are tail-recursive, in which the general idiom is to write to the head and then reverse at the end.
create(N) -> create(1, N, []).
create(M, M, Acc) -> lists:reverse([M | Acc]);
create(N, M, Acc) when N < M -> create(N + 1, M, [N | Acc]).
(Of course, with this specific example, you can alternatively build the results in the reverse order going down to 1 instead of up to M, which would make the lists:reverse call unnecessary.)
If create/2 (or create/3) is not exported and you put an appropriate guard on create/1, the extra N < M guard might be overkill. I generally only check on the exported functions and trust my own internal functions.
create(N,N) -> [N];
create(N,M) -> [N|create(N + 1, M)]. % Don't use ++ to prefix a single element.
This isn't quite the same (you could supply -5), but it behaves the same if you supply meaningful inputs. I wouldn't bother with the extra check anyway, since the process will crash very quickly either way.
BTW, you have a recursion depth problem with the code as-is. This will fix it:
create(N) ->
create(1, N, []).
create(N, N, Acc) -> [N|Acc];
create(N, M, Acc) -> create(N, M - 1, [M|Acc]).
I don't really think you have over used guards. There are two cases:
The first is the explicit equality test in the first clause of create/2
create(N, M) when N =:= M -> [M];
Some have suggested transforming this to use pattern matching like
create(N, N) -> [N];
In this case it makes no difference as the compiler internally transforms the pattern matching version to what you have written. You can safely pick which version you think feels best in each case.
In the second case you need some form of sanity check that the value of the argument in the range you expect it to be. Doing in every loop is unnecessary and I would move it to an equivalent test in create/1:
create(M) when M > 1 -> create(1, M).
If you want to use an accumulator I would personally use the count version as it saves reversing the list at the end. If the list is not long I think the difference is very small and you can pick the version which feels most clear to you. Anyway, it is very easy to change later if you find it to be critical.