• Nested "Maybe"

    From Ben Bacarisse@21:1/5 to All on Fri Apr 9 22:13:19 2021
    This group is looking quiet, but you never know...

    Recently I wanted a type that adds another alternative to Maybe,
    specifically an approximate result, so I wrote (somewhat without
    thinking)

    data Approximate a = Roughly a | Maybe a

    Haskell does not complain about the type (after all, it just looks like
    I'm defining a constructor called Maybe) but, equally obviously, I can't
    write a function like this

    f a | a < 0 = Nothing
    | a > 10000 = Roughly (sqrt a)
    | otherwise = Just (a / 2)

    without type errors. I can nest the Maybe in a new type:

    data Approximate a = Roughly a | Exactly (Maybe a)

    f a | a < 0 = Exactly Nothing
    | a > 10000 = Roughly (sqrt a)
    | otherwise = Exactly (Just (a / 2))

    but I can't help wondering if I'm missing a neater way to do this.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Carroll@21:1/5 to Ben Bacarisse on Fri Apr 9 17:33:50 2021
    On 405 Mar 2020, Ben Bacarisse wrote:

    Recently I wanted a type that adds another alternative to Maybe,
    specifically an approximate result, so I wrote (somewhat without
    thinking)

    data Approximate a = Roughly a | Maybe a

    Haskell does not complain about the type (after all, it just looks like
    I'm defining a constructor called Maybe)

    Yes, I think that's exactly what you're doing, unconnected with the type
    Maybe.

    (snip)
    I can nest the Maybe in a new type:

    data Approximate a = Roughly a | Exactly (Maybe a)

    f a | a < 0 = Exactly Nothing
    | a > 10000 = Roughly (sqrt a)
    | otherwise = Exactly (Just (a / 2))

    That's what I would have done, depending on why I wanted to use Maybe at
    all. E.g., if you don't need much of what Maybe does, you could ignore
    it and define your own three-option type and reimplement the Maybe-like
    stuff you do need. Or you may find you get much of what you need if you
    wrap the other way, e.g., leave it as a,

    data Approximate a = Roughly a | Exactly a

    and use Maybe (Approximate a).

    but I can't help wondering if I'm missing a neater way to do this.

    I'm not aware of one but I know only "pedestrian" Haskell so somebody,
    perhaps more familiar with esoteric extensions, may be able to show us
    some magic.

    -- Mark

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Paul Rubin on Fri Apr 9 14:27:12 2021
    Paul Rubin <no.email@nospam.invalid> writes:
    data Precision a = Roughly a | Exactly a
    data Approximate a = Maybe (Precision a)

    Alternatively maybe you want an actual 3-way Maybe, e.g.

    data Approximate a = Invalid | Roughly a | Exactly a

    and then you could write typeclass instances (monad, monoid, etc.)
    analogously with Maybe.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Ben Bacarisse on Fri Apr 9 14:24:05 2021
    Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
    data Approximate a = Roughly a | Exactly (Maybe a)

    f a | a < 0 = Exactly Nothing
    | a > 10000 = Roughly (sqrt a)
    | otherwise = Exactly (Just (a / 2))

    but I can't help wondering if I'm missing a neater way to do this.

    That looks inside out? I.e. the Maybe should be on the outside.

    data Precision a = Roughly a | Exactly a
    data Approximate a = Maybe (Precision a)

    f a | a < 0 = Nothing
    | a > 10000 = Just (Roughly (sqrt a))
    | otherwise = Just (Exactly (a/2))

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