Discussion:
Black Swan
2018-07-16 17:57:43 UTC
I'm struggling with the following function:

The following declaration works:

data DividedResult = Result Integer | DividedByZero deriving (Eq, Show)

dividedBy num denom =
let
(count,remainder,success) = x num denom 0
in if success then (Result count) else DividedByZero
where
x num denom count
| denom == 0 = (0,0,False)
| num < denom = (count,num,True)
| otherwise = x (num - denom) denom (count + 1)

When I check the type of dividedBy, I get

*Lib> :t dividedBy
dividedBy :: (Num b, Ord b) => b -> b -> DividedResult

However, if I try to add the type declaration line:

dividedBy :: (Num a, DividedResult b) => a -> a -> b

The module fails to load, yielding the following error:

Expected a constraint, but DividedResult has kind *
In the type signature:
dividedBy :: (Num a, DividedResult b) => a -> a -> b
|
10 | dividedBy :: (Num a, DividedResult b) => a -> a -> b
| ^^^^^^^^^^^^^

Could someone please kindly point out my mistake and suggest a type declaration line that works?
Florian Weimer
2018-07-16 21:07:25 UTC
Post by Black Swan
When I check the type of dividedBy, I get
*Lib> :t dividedBy
dividedBy :: (Num b, Ord b) => b -> b -> DividedResult
dividedBy :: (Num a, DividedResult b) => a -> a -> b
These two types are not the same. Why do you think the second type
would work? There are two problems: DividedResult doesn't take a type
parameter, and functions of types as general as Num a => a -> b do not
really exist.
Black Swan
2018-07-17 15:01:29 UTC
Post by Florian Weimer
Post by Black Swan
When I check the type of dividedBy, I get
*Lib> :t dividedBy
dividedBy :: (Num b, Ord b) => b -> b -> DividedResult
dividedBy :: (Num a, DividedResult b) => a -> a -> b
These two types are not the same. Why do you think the second type
would work? There are two problems: DividedResult doesn't take a type
parameter, and functions of types as general as Num a => a -> b do not
really exist.

dividedBy :: (Num n, Ord n) => n -> n -> DividedResult
Black Swan
2018-07-17 15:07:40 UTC
Post by Florian Weimer
Post by Black Swan
When I check the type of dividedBy, I get
*Lib> :t dividedBy
dividedBy :: (Num b, Ord b) => b -> b -> DividedResult
dividedBy :: (Num a, DividedResult b) => a -> a -> b
These two types are not the same. Why do you think the second type
would work? There are two problems: DividedResult doesn't take a type
parameter, and functions of types as general as Num a => a -> b do not
really exist.
Got it! Thank you!

I was confused between type and class. I should have declare the function as:

dividedBy :: (Num n, Ord n) => n -> n -> DividedResult