0

I need to define a haskell function:

func :: Int -> Int func 1 = 1 func 2 = 2 func x = x+1 

So that it allows only positive numbers. I've already had a look at a similar question: Non-negative integers

And wrote this:

newtype Positive a = Positive a toPositive :: (Num a, Ord a) => a -> Positive a toPositive x | x < 0 = error "number cannot be negative" | otherwise = Positive x func :: Positive a -> a func (Positive n) = n 

Which is however already throwing errors. Thoughts?

Update:

Sample error:

*Main> func 1 <interactive>:32:6: No instance for (Num (Positive a0)) arising from the literal `1' Possible fix: add an instance declaration for (Num (Positive a0)) In the first argument of `func', namely `1' In the expression: func 1 In an equation for `it': it = func 1 *Main> 
4
  • It works perfectly for me. What errors are you getting? Commented May 1, 2014 at 14:06
  • Updated above with sample error Commented May 1, 2014 at 14:08
  • 2
    Try calling func $ toPositive 1 Commented May 1, 2014 at 14:09
  • It works with positive values, but I get the following for negative: *Main> func $ toPositive -1 <interactive>:34:8: Couldn't match expected type Positive a0' with actual type a1 -> Positive a1' In the first argument of (-)', namely toPositive' In the second argument of ($)', namely toPositive - 1' In the expression: func $ toPositive - 1 Commented May 1, 2014 at 14:11

1 Answer 1

2

You forgot to call toPositive to convert an Int to a Positive. Call it this way:

func $ toPositive 1 

Also, a quirk of Haskell is its handling of negative number literals. To avoid confusion with the subtraction operator, you must wrap them in parentheses:

func $ toPositive (-1) 
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, yeah, this works :) Is there any way that I can avoid calling "$ toPositive" and just use "func (-1)"?
Also, when I try adding "func 0 = 0" or "func (Positive 0) = 0" I get... dynprog.hs:9:16: No instance for (Num a) arising from the literal 0' Possible fix: add (Num a) to the context of the type signature for func :: Positive a -> a In the pattern: 0 In the pattern: Positive 0 In an equation for func': func (Positive 0) = 2 Failed, modules loaded: none.
You could write a new func that takes an Int as an argument, and calls toPositive internally. However that starts to defeat the purpose of what you're doing. If you make a new type, you have to convert to and from that type. You could also scrap the Positive type entirely, and just explicitly check for negative input in func.
I've tried doing that, but then when I try returning an error I get an error saying an "Int" was expected as a return type?
If your question has gotten larger, consider making another edit to your question, posting more code and a fuller explanation of what you're trying to do, and what errors you're getting. Comments are an inefficient way to have this conversation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.