My aim is to compute the average of a float list. It can however occur that a list is empty, so the computation will be 0. /. 0. = nan but in those cases I want to return 0. instead of nan.
My code looks something like this:
let avg lst =
(*computation of sum of the list through the length of it *)
try sum lst /. length lst
with
| Not_found -> 0.0
| nan -> 0.
But my second with-case is seen as a variable instead of nan by the compiler.
How can I check for a nan in an try/with - Error block?
Rather than catching an exceptional value after the fact, it will be cleaner to handle the empty list separately:
let avg = function
| [] -> 0.
| l -> sum l /. length l
If you really want to test for nan, you can do it with
let avg l =
let res = sum l /. length l in
if Float.is_nan res then 0. else res
It is unclear to me why you are catching a Not_found exception, but if this is really necessary too, you can write:
let avg l =
match sum l /. length l with
| exception Not_found -> 0.
| value ->
if Float.is_nan value then 0. else value
What does attempting to divide by 0. actually return in OCaml?
utop # 1. /. 0.;;
- : float = infinity
Can we test for equality with this value?
utop # 1. /. 0. = infinity;;
- : bool = true
That leads us to something like:
try
let avg = sum lst /. length lst in
if avg <> infinity then avg
else 0.
with
| Not_found -> 0.
But as of OCaml 4.02, we can incorporate exception handling into match, letting us express this perhaps a bit more clearly.
match sum lst /. length lst with
| avg when avg <> infinity -> avg
| _ -> 0.
| exception Not_found -> 0.
One thing you don't want to do is:
match sum lst /. length lst with
| infinity -> 0.
| avg -> avg
| exception Not_found -> 0.
When you use match this way, it is not testing if the value being matched equals infinity. Rather OCaml is binding the name infinity to that value. The above would return 0. for all cases where the exception Not_found is not thrown.
In fact, if you try this, OCaml will issue a warning: this match case is unused. This indicates that the avg pattern can never be reached.
Related
In the code below, lv_sum_openamount should be 3.45 but the program rounds the number as 3.
I want lv_sum_openamount as 3.
How can I do that ?
DATA(lv_sum_openamount) = REDUCE dmbtr_cs( INIT sum = 0 FOR wa_amnt IN <fs_comp> NEXT sum += wa_amnt-open_amount.
LOOP AT <fs_comp> ASSIGNING <fs_comp_alv>.
TRY.
<fs_comp_alv>-pull_amount = ( <fs_pack>-reamount / lv_sum_openamount ) * <fs_comp_alv>-open_amount.
CATCH cx_sy_zerodivide.
<fs_comp_alv>-pull_amount = 0.
ENDTRY.
ENDLOOP.
The culprit is the part INIT sum = 0.
0 is an integer, so the type for sum gets automatically derived as an integer. That means that the REDUCE-loop then uses integer arithmetic, so its output is rounded down.
Try INIT sum = CONV dmbtr_cs( 0 ) instead. This will convert the literal of 0 to the type you need and in turn force sum to also get that type.
Here is an example from here. The code looks like that:
sum : (single : Bool) -> isSingleton single -> Nat
sum True x = x
sum False [] = 0
sum False (x :: xs) = x + sum False xs
I've tried to use single instead of False in the last line. But it fails. I think the problem is that the type of sum single xs is either Nat or List Nat, but + requires only Nat operands. But we are inside a clause where single equals False either way. Shouldn't Idris infer it? Why I can't use single here? Is there some reason for it?
Here is the error:
main.idr:14:23-41:
|
14 | sum False (x :: xs) = x + (sum single xs)
| ~~~~~~~~~~~~~~~~~~~
When checking right hand side of Main.sum with expected type
Nat
When checking argument single to Main.sum:
No such variable single
Upd:
It looks like that the problem here is that I can't directly access the variable from type definition. Then I've tried to use implicit arguments like that:
sum : (single : Bool) -> isSingleton single -> Nat
sum True x = x
sum False [] = 0
sum {single} False (x :: xs) = x + sum single xs
It doesn't help either. Maybe I'm using it wrong. Also I've tried the simplest possible variation like that:
sum : (single: Bool) -> isSingleton single -> Nat
sum s list = case s of
True => list
False => case list of
[] => 0
(x::xs) => x + (sum s xs)
But it doesn't compile either:
|
16 | (x::xs) => x + (sum s xs)
| ~~~~~~~~
When checking right hand side of Main.case block in case block in sum at main.idr:12:19 at main.idr:14:19-22 with expected type
Nat
When checking an application of Main.sum:
Type mismatch between
List Nat (Type of xs)
and
isSingleton s (Expected type)
It looks a bit weird for me, because from one point Idris could prove many interesting and complex things, and from another such a simple thins is unavailable. Or maybe I'm doing it wrong.
It's not so much that it can't infer the type of single, as single isn't in scope on the RHS. You could use a named pattern with single on the LHS
sum : (single : Bool) -> isSingleton single -> Nat
sum True x = x
sum False [] = 0
sum single#False (x :: xs) = x + sum single xs
I can't see a way to avoid the named pattern in this case and just use
sum single (x :: xs) = x + sum single xs
as Idris doesn't infer it's a List Nat without the False. I get
|
8 | sum single (x :: xs) = x + sum single xs
| ~~~~~~~~~~~~~~~~~~~~
When checking left hand side of Main.sum:
When checking an application of Main.sum:
Can't disambiguate since no name has a suitable type:
Prelude.List.::, Prelude.Stream.::
An example would be:
fib: Stream Integer
fib#(1::tfib) = 1 :: 1 :: [ a+b | (a,b) <- zip fib tfib]
But this generates the error:
50 | fib#(1::tfib) = 1 :: 1 :: [ a+b | (a,b) <- zip fib tfib]
| ^
unexpected "#(1::tfib)"
expecting "<==", "using", "with", ':', argument expression, constraint argument, expression, function right hand side, implementation
block, implicit function argument, or with pattern
This doesn't look promising given that it doesn't recognize # at the likely position.
Note that the related concept of as-patterns works the same in Haskell and Idris:
growHead : List a -> List a
growHead nnl#(x::_) = x::nnl
growHead ([]) = []
I want to solve the following problem in Haskell:
Let n be a natural number and let A = [d_1 , ..., d_r] be a set of positive numbers.
I want to find all the positive solutions of the following equation:
n = Sum d_i^2 x_i.
For example if n= 12 and the set A= [1,2,3]. I would like to solve the following equation over the natural numbers:
x+4y+9z=12.
It's enough to use the following code:
[(x,y,z) | x<-[0..12], y<-[0..12], z<-[0..12], x+4*y+9*z==12]
My problem is if n is not fixed and also the set A are not fixed. I don't know how to "produce" a certain amount of variables indexed by the set A.
Instead of a list-comprehension you can use a recursive call with do-notation for the list-monad.
It's a bit more tricky as you have to handle the edge-cases correctly and I allowed myself to optimize a bit:
solve :: Integer -> [Integer] -> [[Integer]]
solve 0 ds = [replicate (length ds) 0]
solve _ [] = []
solve n (d:ds) = do
let maxN = floor $ fromIntegral n / fromIntegral (d^2)
x <- [0..maxN]
xs <- solve (n - x * d^2) ds
return (x:xs)
it works like this:
It's keeping track of the remaining sum in the first argument
when there this sum is 0 where are obviously done and only have to return 0's (first case) - it will return a list of 0s with the same length as the ds
if the remaining sum is not 0 but there are no d's left we are in trouble as there are no solutions (second case) - note that no solutions is just the empty list
in every other case we have a non-zero n (remaining sum) and some ds left (third case):
now look for the maximum number that you can pick for x (maxN) remember that x * d^2 should be <= n so the upper limit is n / d^2 but we are only interested in integers (so it's floor)
try all from x from 0 to maxN
look for all solutions of the remaining sum when using this x with the remaining ds and pick one of those xs
combine x with xs to give a solution to the current subproblem
The list-monad's bind will handle the rest for you ;)
examples
λ> solve 12 [1,2,3]
[[0,3,0],[3,0,1],[4,2,0],[8,1,0],[12,0,0]]
λ> solve 37 [2,3,4,6]
[[3,1,1,0],[7,1,0,0]]
remark
this will fail when dealing with negative numbers - if you need those you gonna have to introduce some more cases - I'm sure you figure them out (it's really more math than Haskell at this point)
Some hints:
Ultimately you want to write a function with this signature:
solutions :: Int -> [Int] -> [ [Int] ]
Examples:
solutions 4 [1,2] == [ [4,0], [0,1] ]
-- two solutions: 4 = 4*1^2 + 0*2^2, 4 = 0*1^2 + 1*2^2
solutions 22 [2,3] == [ [1,2] ]
-- just one solution: 22 = 1*2^2 + 2*3^2
solutions 10 [2,3] == [ ]
-- no solutions
Step 2. Define solutions recursively based on the structure of the list:
solutions x [a] = ...
-- This will either be [] or a single element list
solutions x (a:as) = ...
-- Hint: you will use `solutions ... as` here
As title says, I don't understand why f^:proposition^:_ y is a while loop. I have actually used it a couple times, but I don't understand how it works. I get that ^: repeats functions, but I'm confused by its double use in that statement.
I also can't understand why f^:proposition^:a: y works. This is the same as the previous one but returns the values from all the iterations, instead of only the last one as did the one above.
a: is an empty box and I get that has a special meaning used with ^: but even after having looked into the dictionary I couldn't understand it.
Thanks.
Excerpted and adapted from a longer writeup I posted to the J forums in 2009:
while =: ^:break_clause^:_
Here's an adverb you can apply to any code (which would equivalent of the
loop body) to create a while loop. In case you haven't seen it before, ^: is the power conjunction. More specifically, the phrase f^:n y applies the function f to the argument y exactly n times. The count n maybe be an integer or a function which applied to y produces an integer¹.
In the adverb above, we see the power conjunction twice, once in ^:break_clause and again in ^:_ . Let's first discuss the latter. That _ is J's notation for infinity. So, read literally, ^:_ is "apply the function an infinite number of times" or "keep reapplying forever". This is related to a while-loop's function, but it's not very useful if applied literally.
So, instead, ^:_ and its kin were defined to mean "apply a function to its limit", that is, "keep applying the function until its output matches its input". In that case, applying the function again would have no effect, because the next iteration would have the same input as the previous (remember that J is a functional language). So there's
no point in applying the function even once more: it has reached its limit.
For example:
cos=: 2&o. NB. Cosine function
pi =: 1p1 NB. J's notation for 1*pi^1 analogous to scientific notation 1e1
cos pi
_1
cos cos cos pi
0.857553
cos^:3 pi
0.857553
cos^:10 pi
0.731404
cos^:_ pi NB. Fixed point of cosine
0.739085
Here, we keep applying cosine until the answer stops changing: cosine has reached its fixed point, and more applications are superfluous. We can visualize this by showing the
intermediate steps:
cos^:a: pi
3.1415926535897 _1 0.54030230586813 ...73 more... 0.73908513321512 0.73908513321
So ^:_ applies a function to its limit. OK, what about ^:break_condition? Again, it's the same concept: apply the function on the left the number of times specified by the function on the right. In the case of _ (or its function-equivalent, _: ) the output is "infinity", in the case of break_condition the output will be 0 or 1 depending on the input (a break condition is boolean).
So if the input is "right" (i.e. processing is done), then the break_condition will be 0, whence loop_body^:break_condition^:_ will become loop_body^:0^:_ . Obviously, loop_body^:0 applies the loop_body zero times, which has no effect.
To "have no effect" is to leave the input untouched; put another way, it copies the input to the output ... but if the input matches the output, then the function has reached its limit! Obviously ^:_: detects this fact and terminates. Voila, a while loop!
¹ Yes, including zero and negative integers, and "an integer" should be more properly read as "an arbitrary array of integers" (so the function can be applied at more than one power simultaneously).
f^:proposition^:_ is not a while loop. It's (almost) a while loop when proposition returns 1 or 0. It's some strange kind of while loop when proposition returns other results.
Let's take a simple monadic case.
f =: +: NB. Double
v =: 20 > ] NB. y less than 20
(f^:v^:_) 0 NB. steady case
0
(f^:v^:_) 1 NB. (f^:1) y, until (v y) = 0
32
(f^:v^:_) 2
32
(f^:v^:_) 5
20
(f^:v^:_) 21 NB. (f^:0) y
21
This is what's happening: every time that v y is 1, (f^:1) y is executed. The result of (f^:1) y is the new y and so on.
If y stays the same for two times in a row → output y and stop.
If v y is 0→ output y and stop.
So f^:v^:_ here, works like double while less than 20 (or until the result doesn't change)
Let's see what happens when v returns 2/0 instead of 1/0.
v =: 2 * 20 > ]
(f^:v^:_) 0 NB. steady state
0
(f^:v^:_) 1 NB. (f^:2) 1 = 4 -> (f^:2) 4 = 16 -> (f^:2) 16 = 64 [ -> (f^:0) 64 ]
64
(f^:v^:_) 2 NB. (f^:2) 2 = 8 -> (f^:2) 8 = 32 [ -> (f^:0) 32 ]
32
(f^:v^:_) 5 NB. (f^:2) 5 = 20 [ -> (f^:0) 20 ]
20
(f^:v^:_) 21 NB. [ (f^:0) 21 ]
21
You can have many kinds of "strange" loops by playing with v. (It can even return negative integers, to use the inverse of f).