• =?UTF-8?B?VHlwZSBxdWVzdGlvbg==?=

    From =?UTF-8?B?QmxhY2sgU3dhbg==?=@21:1/5 to All on Mon Jul 16 18:02:19 2018
    From:
    Black Swan
    Subject:
    Haskell question
    Date:
    07.02.2106 17:28
    Newsgroups:
    comp.lang.functional


    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 | 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
    | ^^^^^^^^^^^^^
    Failed, no modules loaded.

    Could someone please kindly point out my mistake and suggest a type declaration line that works?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Carroll@21:1/5 to Black Swan on Mon Jul 16 20:56:06 2018
    On 16 Jul 2018, Black Swan wrote:

    I'm struggling with the following function:

    The following declaration works:

    Don't know what happened to your whitespace here:

    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 | otherwise = x (num - denom) denom (count + 1)

    I can't quite make sense of this even if I try to correct the indents.
    What's going on with the num guard bit?

    If your news client is causing problems, happy to take a look at this
    from some URL instead.

    -- Mark

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Carroll@21:1/5 to Black Swan on Mon Jul 16 21:05:06 2018
    On 16 Jul 2018, Black Swan wrote:

    data DividedResult = Result Integer | DividedByZero deriving (Eq, Show)
    (snip)
    *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
    (snip)
    Could someone please kindly point out my mistake and suggest a type declaration line that works?

    Beyond the issues with the code as presented, DividedResult is just an algebraic datatype. The constraint syntax you're using in the type
    signature is for classes, not types: classes simply limit the types that
    can be used to fill in the type variables like a and b. Also you do need
    the Ord because that's what "<" needs. It might help if you back up and
    let us know what you're hoping this type signature will achieve that the inferred one doesn't. It may help to note that in many places where in
    C++ or whatever you might use a thing called a class, in Haskell it will
    still simply be a type, with classes being at another step removed and
    not always needed in the same way.

    -- Mark

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?B?QmxhY2sgU3dhbg==?=@21:1/5 to All on Tue Jul 17 15:04:29 2018
    On Mon Jul 16 21:05:06 2018 Mark Carroll wrote:
    On 16 Jul 2018, Black Swan wrote:

    data DividedResult = Result Integer | DividedByZero deriving (Eq, Show)
    (snip)
    *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
    (snip)
    Could someone please kindly point out my mistake and suggest a type declaration line that works?

    Beyond the issues with the code as presented, DividedResult is just an algebraic datatype. The constraint syntax you're using in the type
    signature is for classes, not types: classes simply limit the types that
    can be used to fill in the type variables like a and b. Also you do need
    the Ord because that's what "<" needs. It might help if you back up and
    let us know what you're hoping this type signature will achieve that the inferred one doesn't. It may help to note that in many places where in
    C++ or whatever you might use a thing called a class, in Haskell it will still simply be a type, with classes being at another step removed and
    not always needed in the same way.

    -- Mark

    Thanks Mark, much appreciated!

    I am starting to get the hang of it. Just figured out that the declaration that I needed was:

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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Carroll@21:1/5 to Black Swan on Tue Jul 17 16:11:27 2018
    On 17 Jul 2018, Black Swan wrote:

    On Mon Jul 16 21:05:06 2018 Mark Carroll wrote:
    On 16 Jul 2018, Black Swan wrote:
    (snip)
    *Lib> :t dividedBy
    dividedBy :: (Num b, Ord b) => b -> b -> DividedResult
    (snip)
    I am starting to get the hang of it. Just figured out that the declaration that I needed was:

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

    Glad to hear it. Kudos to the type inference system then. (-:

    -- Mark

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)