[Haskell-cafe] Disambiguating a Num/RealFrac instance

7 views
Skip to first unread message

ami...@gmail.com

unread,
May 28, 2015, 1:18:54 PM5/28/15
to Haskell Cafe
Given:

data GPA = F Float | Excuse String

class ToGPA a where
giveGPA :: a -> GPA

Is there any way (without IncoherentInstances or Rebindablesyntax) that I can let the user write e.g. "giveGPA 4.0" (and "giveGPA 4") and get back "F 4" without getting type errors that "4.0"'s type is ambiguous? I can guarantee there won't be any additional instances to "ToGPA"

(For my uses, I really (actually!) don't want to make the user write e.g. "F 4.0")

I've gotten this working, once with IncoherentInstances and once with RebindableSyntax, but both of those flags feel pretty dirty.

Thanks,
Tom
_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Brandon Allbery

unread,
May 28, 2015, 1:28:29 PM5/28/15
to Tom Murphy, Haskell Cafe
On Tue, May 26, 2015 at 8:35 PM, <ami...@gmail.com> wrote:
Is there any way (without IncoherentInstances or Rebindablesyntax) that I can let the user write e.g. "giveGPA 4.0" (and "giveGPA 4") and get back "F 4" without getting type errors that "4.0"'s type is ambiguous? I can guarantee there won't be any additional instances to "ToGPA"

A typeclass with only one instance is nonsensical, and often a symptom of trying to use typeclasses as OO classes. All it's doing here is hurting you.

In this case, you don't really want to do anything special at all:

    giveGPA :: Float -> GPA
    giveGPA f = F f

and let Haskell's numeric overloading resolve 4 as (fromInteger 4 :: Float). (Use of the typeclass blocks this.)

--
brandon s allbery kf8nh                               sine nomine associates
allb...@gmail.com                                  ball...@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net

Adam Gundry

unread,
May 28, 2015, 1:44:00 PM5/28/15
to ami...@gmail.com, Haskell Cafe
[Sorry, CCing haskell-cafe rather than ghc-devs!]

On 28/05/15 18:28, Brandon Allbery wrote:
> On Tue, May 26, 2015 at 8:35 PM, <ami...@gmail.com
> <mailto:ami...@gmail.com>> wrote:
>
> Is there any way (without IncoherentInstances or Rebindablesyntax)
> that I can let the user write e.g. "giveGPA 4.0" (and "giveGPA 4")
> and get back "F 4" without getting type errors that "4.0"'s type is
> ambiguous? I can guarantee there won't be any additional instances
> to "ToGPA"
>
>
> A typeclass with only one instance is nonsensical, and often a symptom
> of trying to use typeclasses as OO classes. All it's doing here is
> hurting you.

Like Brandon, I suspect this probably isn't what you should do. But if
you *really* want to do it, this works:

{-# LANGUAGE ExtendedDefaultRules, FlexibleInstances #-}

default (Float)

data GPA = F Float | Excuse String

class ToGPA a where
giveGPA :: a -> GPA

instance ToGPA Float where
giveGPA = F

instance ToGPA String where
giveGPA = Excuse

x = giveGPA 4
y = giveGPA 4.0
z = giveGPA "Hello"

For more information:
https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/interactive-evaluation.html#extended-default-rules

Hope this helps,

Adam


--
Adam Gundry, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com/

ami...@gmail.com

unread,
May 29, 2015, 9:39:58 PM5/29/15
to Adam Gundry, Haskell Cafe
Oh apologies -- it looks like my contrived example was a little too contrived. I'm actually using a MPTC, so the type would be more like:

class ToGPA a b where
toGPA :: a -> GPA

ExtendedDefaultRules doesn't work with MPTCs it seems.


Tom

Reply all
Reply to author
Forward
0 new messages