testing for exceptions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

testing for exceptions

Roelof Wobben
Hello,

I have made this exercise which can be found at the Craft of Functional
Programming  book.

-- exercise 32

-- Suppose we have to raise 2 to the power n. If n is even, 2*m say, then
-- 2n = 22*m = (2m)2
-- If n is odd, 2*m+l say, then
-- 2n = 22*m+l = (2n)2*2
-- Give a recursive function to compute 2n which uses these insights.

f2 :: Integer -> Integer
f2 n
   | n < 0   = error "This will only run for positive numbers"
   | n == 0  = 1
   | even n = f2 ( n `div` 2) ^ 2
   | odd n  = (f2 ( n `div` 2) ^ 2) * 2


Now I have to make Hunit tests for it,

But is there a way I can test if the error message is shown when a
negative number is being used ?

Roelof

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

joachifm
On Sat, Oct 31, 2015, at 11:16 AM, Roelof Wobben wrote:
> [...]
> But is there a way I can test if the error message is shown when a
> negative number is being used ?

Something like (untested)

```
import qualified Control.Exception as E

isErrorCall :: String -> a -> IO Bool
isErrorCall s x = (E.evaluate x >> return False)
                  `E.catch` (\(E.ErrorCall e) -> return $ e == s)

myTest = isErrorCall "This will only run for positive numbers" . f2

{-
>> myTest (-1) = return True
>> myTest 100 = return False
-}
```

HTH,

Joachim
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Darren Grant-2
In reply to this post by Roelof Wobben

Unfrotunately the answer to this is not simple:

http://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function

'error' more or less terminates the program in an unreasonable way.

It would be preferable for f2 to result in a type that can contain the error result to be parsed.

Cheers,
Darren

On Oct 31, 2015 21:16, "Roelof Wobben" <[hidden email]> wrote:
Hello,

I have made this exercise which can be found at the Craft of Functional Programming  book.

-- exercise 32

-- Suppose we have to raise 2 to the power n. If n is even, 2*m say, then
-- 2n = 22*m = (2m)2
-- If n is odd, 2*m+l say, then
-- 2n = 22*m+l = (2n)2*2
-- Give a recursive function to compute 2n which uses these insights.

f2 :: Integer -> Integer
f2 n
  | n < 0   = error "This will only run for positive numbers"
  | n == 0  = 1
  | even n = f2 ( n `div` 2) ^ 2
  | odd n  = (f2 ( n `div` 2) ^ 2) * 2


Now I have to make Hunit tests for it,

But is there a way I can test if the error message is shown when a negative number is being used ?

Roelof

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Roelof Wobben
Op 31-10-2015 om 11:40 schreef Darren Grant:

>
> Unfrotunately the answer to this is not simple:
>
> http://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function
>
> 'error' more or less terminates the program in an unreasonable way.
>
> It would be preferable for f2 to result in a type that can contain the
> error result to be parsed.
>
> Cheers,
> Darren
>
>


Oke,

So I have to change the type of f2.

To what do I have to change it to make it testable.

Roelof

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Tom Ellis
On Sat, Oct 31, 2015 at 11:46:15AM +0100, Roelof Wobben wrote:

> Op 31-10-2015 om 11:40 schreef Darren Grant:
> >
> >Unfrotunately the answer to this is not simple:
> >
> >http://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function
> >
> >'error' more or less terminates the program in an unreasonable way.
> >
> >It would be preferable for f2 to result in a type that can contain
> >the error result to be parsed.
>
> So I have to change the type of f2.
>
> To what do I have to change it to make it testable.

For example, Integer -> Maybe Integer
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Darren Grant-2
In reply to this post by Roelof Wobben

I'd expect most Haskellers to recommend something like,

  f2 :: Integer -> Either Integer ErrorString

where ErrorString is some specific error value type. (String may suffice for you.)

This is a safe general solution, but there are many potentially more specific possibilities that might make your program simpler depending on how this function relates to the context it will be used in.

Cheers,
Darren

On Oct 31, 2015 21:46, "Roelof Wobben" <[hidden email]> wrote:
Op 31-10-2015 om 11:40 schreef Darren Grant:

Unfrotunately the answer to this is not simple:

http://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function

'error' more or less terminates the program in an unreasonable way.

It would be preferable for f2 to result in a type that can contain the error result to be parsed.

Cheers,
Darren




Oke,

So I have to change the type of f2.

To what do I have to change it to make it testable.

Roelof

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Roel van Dijk-3
Small nitpick, but I would generally put the "exception" or "error" in the Left part of an Either and a correct result in the Right part. 

This has some advantages. 
1 - Right is right as opposed to wrong. Easy to remember mnemonic.
2 - It fits neatly with the Monad (Either e) instance.

Roelof, a nice exercise is to first implement your f2 function with the Integer -> Maybe Integer type and then with Integer -> Either String Integer.
If you realize that both Monad Maybe and Monad (Either e) you can use almost the same code.

2015-10-31 12:04 GMT+01:00 Darren Grant <[hidden email]>:

I'd expect most Haskellers to recommend something like,

  f2 :: Integer -> Either Integer ErrorString

where ErrorString is some specific error value type. (String may suffice for you.)

This is a safe general solution, but there are many potentially more specific possibilities that might make your program simpler depending on how this function relates to the context it will be used in.

Cheers,
Darren

On Oct 31, 2015 21:46, "Roelof Wobben" <[hidden email]> wrote:
Op 31-10-2015 om 11:40 schreef Darren Grant:

Unfrotunately the answer to this is not simple:

http://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function

'error' more or less terminates the program in an unreasonable way.

It would be preferable for f2 to result in a type that can contain the error result to be parsed.

Cheers,
Darren




Oke,

So I have to change the type of f2.

To what do I have to change it to make it testable.

Roelof

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe



_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Roelof Wobben
Op 31-10-2015 om 12:10 schreef Roel van Dijk:
Small nitpick, but I would generally put the "exception" or "error" in the Left part of an Either and a correct result in the Right part. 

This has some advantages. 
1 - Right is right as opposed to wrong. Easy to remember mnemonic.
2 - It fits neatly with the Monad (Either e) instance.

Roelof, a nice exercise is to first implement your f2 function with the Integer -> Maybe Integer type and then with Integer -> Either String Integer.
If you realize that both Monad Maybe and Monad (Either e) you can use almost the same code.

2015-10-31 12:04 GMT+01:00 Darren Grant <[hidden email]>:

I'd expect most Haskellers to recommend something like,

  f2 :: Integer -> Either Integer ErrorString

where ErrorString is some specific error value type. (String may suffice for you.)

This is a safe general solution, but there are many potentially more specific possibilities that might make your program simpler depending on how this function relates to the context it will be used in.

Cheers,
Darren

On Oct 31, 2015 21:46, "Roelof Wobben" <[hidden email]> wrote:
Op 31-10-2015 om 11:40 schreef Darren Grant:

Unfrotunately the answer to this is not simple:

http://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function

'error' more or less terminates the program in an unreasonable way.

It would be preferable for f2 to result in a type that can contain the error result to be parsed.

Cheers,
Darren





Here my try for the Maybe


f2Maybe :: Integer -> Maybe Integer
f2Maybe n
   | n > 0  = Nothing
   | n == 0  = Just 1
   | even n = Just (f2Maybe ( n `div` 2) ^ 2)
   | odd n  = Just ((f2Maybe ( n `div` 2) ^ 2) * 2)
  

But it will not compile , the clauses for even and odd do not work.

Both maybe and either are not explained in the first 4 chapter of the Craft book.

Roelof


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Darren Grant-2
You're very close. Take a look at the even clause: Let (k :: Integer), and consider how the type of the expression producing the error,

  Just (f2Maybe k)

differs from the type of the expression,

  (f2Maybe k)

Cheers,
Darren


On Sat, Oct 31, 2015 at 11:27 PM, Roelof Wobben <[hidden email]> wrote:
Op 31-10-2015 om 12:10 schreef Roel van Dijk:
Small nitpick, but I would generally put the "exception" or "error" in the Left part of an Either and a correct result in the Right part. 

This has some advantages. 
1 - Right is right as opposed to wrong. Easy to remember mnemonic.
2 - It fits neatly with the Monad (Either e) instance.

Roelof, a nice exercise is to first implement your f2 function with the Integer -> Maybe Integer type and then with Integer -> Either String Integer.
If you realize that both Monad Maybe and Monad (Either e) you can use almost the same code.

2015-10-31 12:04 GMT+01:00 Darren Grant <[hidden email]>:

I'd expect most Haskellers to recommend something like,

  f2 :: Integer -> Either Integer ErrorString

where ErrorString is some specific error value type. (String may suffice for you.)

This is a safe general solution, but there are many potentially more specific possibilities that might make your program simpler depending on how this function relates to the context it will be used in.

Cheers,
Darren

On Oct 31, 2015 21:46, "Roelof Wobben" <[hidden email]> wrote:
Op 31-10-2015 om 11:40 schreef Darren Grant:

Unfrotunately the answer to this is not simple:

http://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function

'error' more or less terminates the program in an unreasonable way.

It would be preferable for f2 to result in a type that can contain the error result to be parsed.

Cheers,
Darren





Here my try for the Maybe


f2Maybe :: Integer -> Maybe Integer
f2Maybe n
   | n > 0  = Nothing
   | n == 0  = Just 1
   | even n = Just (f2Maybe ( n `div` 2) ^ 2)
   | odd n  = Just ((f2Maybe ( n `div` 2) ^ 2) * 2)
  

But it will not compile , the clauses for even and odd do not work.

Both maybe and either are not explained in the first 4 chapter of the Craft book.

Roelof


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe



_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Roelof Wobben
Op 31-10-2015 om 13:44 schreef Darren Grant:

> You're very close. Take a look at the even clause: Let (k :: Integer),
> and consider how the type of the expression producing the error,
>
>   Just (f2Maybe k)
>
> differs from the type of the expression,
>
>   (f2Maybe k)
>
> Cheers,
> Darren
>

Just (f2Maybe k) is type Maybe (Maybe Integer)
f2Maybe k is type Maybe Integer

But when I change the code to this :

f2Maybe :: Integer -> Maybe Integer
f2Maybe n
    | n > 0  = Nothing
    | n == 0  = Just 1
    | even n = f2Maybe ( n `div` 2) ^ 2
    | odd n  = (f2Maybe ( n `div` 2) ^ 2) * 2

Then I see this error message :

No instance for (Num (Maybe Integer)) arising from a use of ‘^’
     In the expression: f2Maybe (n `div` 2) ^ 2
     In an equation for ‘f2Maybe’:
         f2Maybe n
           | n > 0 = Nothing
           | n == 0 = Just 1
           | even n = f2Maybe (n `div` 2) ^ 2
           | odd n = (f2Maybe (n `div` 2) ^ 2) * 2
Failed, modules loaded: none.


No instance for (Num (Maybe Integer)) arising from a use of ‘^’
     In the expression: f2Maybe (n `div` 2) ^ 2
     In an equation for ‘f2Maybe’:
         f2Maybe n
           | n > 0 = Nothing
           | n == 0 = Just 1
           | even n = f2Maybe (n `div` 2) ^ 2
           | odd n = (f2Maybe (n `div` 2) ^ 2) * 2
Failed, modules loaded: none.

No instance for (Num (Maybe Integer)) arising from a use of ‘^’
     In the expression: f2Maybe (n `div` 2) ^ 2
     In an equation for ‘f2Maybe’:
         f2Maybe n
           | n > 0 = Nothing
           | n == 0 = Just 1
           | even n = f2Maybe (n `div` 2) ^ 2
           | odd n = (f2Maybe (n `div` 2) ^ 2) * 2
Failed, modules loaded: none.

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Roel van Dijk-3
You are even closer now!

What the type checker is trying to tell you is that it doesn't know how to raise Maybe Integer to some power.

You apply the ^ operator to two values, f2Maybe (n `div` 2) and 2. Let us give them names:

let a = f2Maybe (n `div` 2) :: Maybe Integer
    b = 2 :: Int
in a ^ b

You see that the type of a is Maybe Integer. What does this mean? There are only 2 cases to consider. You have Just an integer or you have Nothing.

You can use the case construct to write the code for both cases.

f2Maybe :: Integer -> Maybe Integer
f2Maybe n
   | n > 0  = Nothing
   | n == 0  = Just 1
   | even n = case f2Maybe (n `div` 2) of
                Just x -> <fill in>
                Nothing -> <fill in>
   | odd n  = case f2Maybe (n `div` 2) of
                Just x -> <fill in>
                Nothing -> <fill in>


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Erik Hesselink
In reply to this post by Darren Grant-2
I think you misinterpreted that answer. As far as I'm aware, `error`
(except in its type) is no less reasonable than other exceptions, and
you can catch it in IO. So as long as you run a test in IO, you can
test for the call to `error` (as Joachim showed in another reply).

Regards,

Erik

On 31 October 2015 at 11:40, Darren Grant <[hidden email]> wrote:

> Unfrotunately the answer to this is not simple:
>
> http://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function
>
> 'error' more or less terminates the program in an unreasonable way.
>
> It would be preferable for f2 to result in a type that can contain the error
> result to be parsed.
>
> Cheers,
> Darren
>
> On Oct 31, 2015 21:16, "Roelof Wobben" <[hidden email]> wrote:
>>
>> Hello,
>>
>> I have made this exercise which can be found at the Craft of Functional
>> Programming  book.
>>
>> -- exercise 32
>>
>> -- Suppose we have to raise 2 to the power n. If n is even, 2*m say, then
>> -- 2n = 22*m = (2m)2
>> -- If n is odd, 2*m+l say, then
>> -- 2n = 22*m+l = (2n)2*2
>> -- Give a recursive function to compute 2n which uses these insights.
>>
>> f2 :: Integer -> Integer
>> f2 n
>>   | n < 0   = error "This will only run for positive numbers"
>>   | n == 0  = 1
>>   | even n = f2 ( n `div` 2) ^ 2
>>   | odd n  = (f2 ( n `div` 2) ^ 2) * 2
>>
>>
>> Now I have to make Hunit tests for it,
>>
>> But is there a way I can test if the error message is shown when a
>> negative number is being used ?
>>
>> Roelof
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> [hidden email]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Darren Grant-2

Good clarification.

Cheers,
Darren

On Nov 1, 2015 01:09, "Erik Hesselink" <[hidden email]> wrote:
I think you misinterpreted that answer. As far as I'm aware, `error`
(except in its type) is no less reasonable than other exceptions, and
you can catch it in IO. So as long as you run a test in IO, you can
test for the call to `error` (as Joachim showed in another reply).

Regards,

Erik

On 31 October 2015 at 11:40, Darren Grant <[hidden email]> wrote:
> Unfrotunately the answer to this is not simple:
>
> http://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function
>
> 'error' more or less terminates the program in an unreasonable way.
>
> It would be preferable for f2 to result in a type that can contain the error
> result to be parsed.
>
> Cheers,
> Darren
>
> On Oct 31, 2015 21:16, "Roelof Wobben" <[hidden email]> wrote:
>>
>> Hello,
>>
>> I have made this exercise which can be found at the Craft of Functional
>> Programming  book.
>>
>> -- exercise 32
>>
>> -- Suppose we have to raise 2 to the power n. If n is even, 2*m say, then
>> -- 2n = 22*m = (2m)2
>> -- If n is odd, 2*m+l say, then
>> -- 2n = 22*m+l = (2n)2*2
>> -- Give a recursive function to compute 2n which uses these insights.
>>
>> f2 :: Integer -> Integer
>> f2 n
>>   | n < 0   = error "This will only run for positive numbers"
>>   | n == 0  = 1
>>   | even n = f2 ( n `div` 2) ^ 2
>>   | odd n  = (f2 ( n `div` 2) ^ 2) * 2
>>
>>
>> Now I have to make Hunit tests for it,
>>
>> But is there a way I can test if the error message is shown when a
>> negative number is being used ?
>>
>> Roelof
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> [hidden email]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

joachifm
The ability to express non-termination is a feature, not a bug. If the
program truly cannot produce a useful result for some input, it should
crash, the earlier the better. Wrapping the return value ONLY to make a
non-total program *appear* total is kind of ugly (and commits you to a
potentially inappropriate/nonsensical model for the problem at hand). It
is cleaner to either constrain the input to values you're prepared to
deal with or crash when the implicit invariant is violated.
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Roelof Wobben
In reply to this post by Roel van Dijk-3
Op 31-10-2015 om 14:56 schreef Roel van Dijk:
You are even closer now!

What the type checker is trying to tell you is that it doesn't know how to raise Maybe Integer to some power.

You apply the ^ operator to two values, f2Maybe (n `div` 2) and 2. Let us give them names:

let a = f2Maybe (n `div` 2) :: Maybe Integer
    b = 2 :: Int
in a ^ b

You see that the type of a is Maybe Integer. What does this mean? There are only 2 cases to consider. You have Just an integer or you have Nothing.

You can use the case construct to write the code for both cases.

f2Maybe :: Integer -> Maybe Integer
f2Maybe n
   | n > 0  = Nothing
   | n == 0  = Just 1
   | even n = case f2Maybe (n `div` 2) of
                Just x -> <fill in>
                Nothing -> <fill in>
   | odd n  = case f2Maybe (n `div` 2) of
                Just x -> <fill in>
                Nothing -> <fill in>



Still confusing.

with even you can have a integer which will be a integer or nothing if there is a number which is not even.
So with 1 it will be Nothing.

but will the odd even be reached ?


Roelof


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Roelof Wobben
Op 31-10-2015 om 17:43 schreef Roelof Wobben:
Op 31-10-2015 om 14:56 schreef Roel van Dijk:
You are even closer now!

What the type checker is trying to tell you is that it doesn't know how to raise Maybe Integer to some power.

You apply the ^ operator to two values, f2Maybe (n `div` 2) and 2. Let us give them names:

let a = f2Maybe (n `div` 2) :: Maybe Integer
    b = 2 :: Int
in a ^ b

You see that the type of a is Maybe Integer. What does this mean? There are only 2 cases to consider. You have Just an integer or you have Nothing.

You can use the case construct to write the code for both cases.

f2Maybe :: Integer -> Maybe Integer
f2Maybe n
   | n > 0  = Nothing
   | n == 0  = Just 1
   | even n = case f2Maybe (n `div` 2) of
                Just x -> <fill in>
                Nothing -> <fill in>
   | odd n  = case f2Maybe (n `div` 2) of
                Just x -> <fill in>
                Nothing -> <fill in>



Still confusing.

with even you can have a integer which will be a integer or nothing if there is a number which is not even.
So with 1 it will be Nothing.

but will the odd even be reached ?


Roelof



Solved both ones like this :

f2Maybe :: Integer -> Maybe Integer
f2Maybe n
   | n < 0  = Nothing
   | otherwise = Just (f3 n )
 
f3 :: Integer -> Integer
f3 n 
  | n == 0  = 1
  | even n = f3 ( n `div` 2) ^ 2
  | odd n  = (f3 ( n `div` 2) ^ 2) * 2 


f2Either :: Integer -> Either String Integer
f2Either n
  | n < 0      = Left "This function works only with positive number"
  | otherwise  = Right (f3 n) 

So I can now test on Nothing or Left "This function works only with positive number" ?

Roelof





_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Darren Grant-2
In reply to this post by joachifm

Great points.

I often run into situations where sketching out non-terminating endpoints leads to a precise domain, but after peer review it becomes clear that a much simpler program would result from compromising with a less precise domain that eliminates these points altogether.

Eliminating branching on constructors in Haskell is a common aspect of this refinement, it's true.

Cheers,
Darren

On Nov 1, 2015 03:18, <[hidden email]> wrote:
The ability to express non-termination is a feature, not a bug. If the
program truly cannot produce a useful result for some input, it should
crash, the earlier the better. Wrapping the return value ONLY to make a
non-total program *appear* total is kind of ugly (and commits you to a
potentially inappropriate/nonsensical model for the problem at hand). It
is cleaner to either constrain the input to values you're prepared to
deal with or crash when the implicit invariant is violated.
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Richard A. O'Keefe
In reply to this post by Roelof Wobben
Simplest hack:

    f2Maybe :: Integer -> Maybe Integer
    f2Maybe n = if n < 0 then Nothing else Just (g n)
      where g 0 = 1
            g n = if odd n then x*2 else x
                  where x = (g (n `div` 2))^2

There is no need to *keep* checking for a negative number in the
recursive code.
>
> f2Maybe :: Integer -> Maybe Integer
> f2Maybe n
>    | n > 0  = Nothing
>    | n == 0  = Just 1
>    | even n = Just (f2Maybe ( n `div` 2) ^ 2)
>    | odd n  = Just ((f2Maybe ( n `div` 2) ^ 2) * 2)

Let's try another tack.
The recursive calls (f2Maybe (n `div` 2))
give you a value of type Maybe Integer.
You want to transform the Integer part.
This is an instance of

 Monad m => m a -> (a -> b) -> m b.

There's something almost like that in Control.Monad:

  liftM :: (a -> b) -> m a -> m b

So what you want is

  liftM (\x -> x^2)   (f2Maybe (n `div` 2))
  liftM (\x -> x^2*2) (f2Maybe (n `div` 2))

So

  f2Maybe n | n < 0 = Nothing
  f2Maybe 0         = Just 1
  f2Maybe n         = liftM (if odd n then (\x -> x^2*2) else (\x -> x^2))
                            (f2Maybe (n `div` 2))

Or you could use 'do' notation:

    f2Maybe n | n < 0 = Nothing
    f2Maybe 0         = Just 1
    f2Maybe n         = do x <- f2Maybe (n `div` 2)
                           return (if odd n then x^2*2 else x^2)

Whatever you do, the key thing is that you HAVE a value
wrapped up in Just and you need to unwrap it, operate on the
value, and rewrap it.

So you could do something like

rewrap _ Nothing  = Nothing
rewrap f (Just x) = Just (f x)

and then

    f2Maybe n | n < 0 = Nothing
    f2Maybe 0         = Just 1
    f2Maybe n         = rewrap (\x -> if odd n then x^2*2 else x^2)
                               (f2Maybe (n `div` 2))

and presto, chango! we've just re-invented liftM under the name
'rewrap'.  



_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Kim-Ee Yeoh
Administrator
In reply to this post by Roel van Dijk-3

On Sat, Oct 31, 2015 at 6:10 PM, Roel van Dijk <[hidden email]> wrote:
Small nitpick, but I would generally put the "exception" or "error" in the Left part of an Either and a correct result in the Right part. 

This has some advantages. 
1 - Right is right as opposed to wrong. Easy to remember mnemonic.
2 - It fits neatly with the Monad (Either e) instance.

I think you're being modest when you call it a "small nitpick." If code can't get Left and Right right, that code immediately becomes very suspicious.

Thus, not

  f2 :: Integer -> Either Integer ErrorString

but

  f2 :: Integer -> Either ErrorString Integer

Nice catch.

-- Kim-Ee

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: testing for exceptions

Darren Grant-2

Oops yes! :)

On Nov 2, 2015 13:38, "Kim-Ee Yeoh" <[hidden email]> wrote:

On Sat, Oct 31, 2015 at 6:10 PM, Roel van Dijk <[hidden email]> wrote:
Small nitpick, but I would generally put the "exception" or "error" in the Left part of an Either and a correct result in the Right part. 

This has some advantages. 
1 - Right is right as opposed to wrong. Easy to remember mnemonic.
2 - It fits neatly with the Monad (Either e) instance.

I think you're being modest when you call it a "small nitpick." If code can't get Left and Right right, that code immediately becomes very suspicious.

Thus, not

  f2 :: Integer -> Either Integer ErrorString

but

  f2 :: Integer -> Either ErrorString Integer

Nice catch.

-- Kim-Ee

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe