Rustom Mody | 26 Dec 15:42 2012
Picon

Non polymorphic numerals option -- avoiding type classes

In haskell, we have

Prelude> :t 4
4 :: Num a => a
Prelude>

This may be nice in its generality but it makes it hard (for me at least) when teaching a beginners course to teach polymorphic vs monomorphic types.  The above leads to even more 'advanced' results like this:

Prelude> :t [[1],2]
[[1],2] :: (Num [t], Num t) => [[t]]


Prelude> [[1],2]

<interactive>:5:6:
    No instance for (Num [t0])
      arising from the literal `2'
    Possible fix: add an instance declaration for (Num [t0])
    In the expression: 2
    In the expression: [[1], 2]
    In an equation for `it': it = [[1], 2]


By contrast in gofer, numeric literals are monomorphic and no such peculiarities arise

? :t [[1],2]
ERROR: Type error in list
*** expression     : [[1],2]
*** term           : 2
*** type           : Int
*** does not match : [Int]

[[1],2]
ERROR: Type error in list
*** expression     : [[1],2]
*** term           : 2
*** type           : Int
*** does not match : [Int]


So is there any set of flags to make haskell literals less polymorphic?
ie I want 3 to have type Int and 3.0 to have type Float.

This is of course for beginning students to not see type classes too early

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
koomi | 26 Dec 20:07 2012
Picon

Re: Non polymorphic numerals option -- avoiding type classes

You should note that GHCi uses extended defaulting rules as explained in
[1].
This means that a literal like 5 will only be of type Num a => a in GHCi
while in a normal Haskell program it will default to some concrete type
(Integer if there are no other constraints). Also, if you define x = 5
in a .hs file and load the file in GHCi, x will have type Integer.

In my short search I could not find out how to reverse this behavior,
:unset -XExtendedDefaultRules does not seem to work.
koomi | 26 Dec 20:18 2012
Picon

Re: Non polymorphic numerals option -- avoiding type classes

Sorry, forgot the link: http://www.haskell.org/ghc/docs/7.0.4/html/users_guide/interactive-evaluation.html
Section 2.4.5 Type defaulting in GHCi
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Roman Cheplyaka | 26 Dec 21:18 2012

Re: Non polymorphic numerals option -- avoiding type classes

* Rustom Mody <rustompmody <at> gmail.com> [2012-12-26 20:12:17+0530]
> So is there any set of flags to make haskell literals less polymorphic?

Yes, there is!

  % ghci -XRebindableSyntax
  GHCi, version 7.6.1: http://www.haskell.org/ghc/  :? for help
  Loading package ghc-prim ... linking ... done.
  Loading package integer-gmp ... linking ... done.
  Loading package base ... linking ... done.
  > import Prelude hiding (fromInteger)
  Prelude> let fromInteger = id
  Prelude> :t 3
  3 :: Integer

Roman
Rustom Mody | 27 Dec 02:00 2012
Picon

Re: Non polymorphic numerals option -- avoiding type classes



On Thu, Dec 27, 2012 at 1:48 AM, Roman Cheplyaka <roma <at> ro-che.info> wrote:
* Rustom Mody <rustompmody <at> gmail.com> [2012-12-26 20:12:17+0530]
> So is there any set of flags to make haskell literals less polymorphic?

Yes, there is!

  % ghci -XRebindableSyntax
  GHCi, version 7.6.1: http://www.haskell.org/ghc/  :? for help
  Loading package ghc-prim ... linking ... done.
  Loading package integer-gmp ... linking ... done.
  Loading package base ... linking ... done.
  > import Prelude hiding (fromInteger)
  Prelude> let fromInteger = id
  Prelude> :t 3
  3 :: Integer

Roman


Thanks Roman -- that helps.
And yet the ghci error is much more obscure than the gofer error:

--- contents of .ghci ---
:set -XRebindableSyntax
let fromInteger = id
------ ghci session -----
$ ghci
GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :t 5
5 :: Integer
Prelude> :t [[1,2],3]

<interactive>:1:8:
    Couldn't match expected type `[Integer]' with actual type `Integer'
    Expected type: Integer -> [Integer]
      Actual type: Integer -> Integer
    In the expression: 3
    In the expression: [[1, 2], 3]


----- The same in gofer -----
Gofer session for:
pustd.pre
? :t [[1,2],3]

ERROR: Type error in list
*** expression     : [[1,2],3]
*** term           : 3
*** type           : Int
*** does not match : [Int]
--------------
So the error is occurring at the point of the fromInteger (= id) but the message does not indicate that

--
http://www.the-magus.in
http://blog.languager.org

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
David Virebayre | 27 Dec 10:03 2012
Picon

Re: Non polymorphic numerals option -- avoiding type classes

Prelude> :t [[1,2],3]

you have a list with 2 elements:
- [1,2]
- 3
the type of [1,2] is [Integer]
the type of 3 is Integer

But all elements in a list must have the same type.

2012/12/27 Rustom Mody <rustompmody <at> gmail.com>:
>
>
> On Thu, Dec 27, 2012 at 1:48 AM, Roman Cheplyaka <roma <at> ro-che.info> wrote:
>>
>> * Rustom Mody <rustompmody <at> gmail.com> [2012-12-26 20:12:17+0530]
>> > So is there any set of flags to make haskell literals less polymorphic?
>>
>> Yes, there is!
>>
>>   % ghci -XRebindableSyntax
>>   GHCi, version 7.6.1: http://www.haskell.org/ghc/  :? for help
>>   Loading package ghc-prim ... linking ... done.
>>   Loading package integer-gmp ... linking ... done.
>>   Loading package base ... linking ... done.
>>   > import Prelude hiding (fromInteger)
>>   Prelude> let fromInteger = id
>>   Prelude> :t 3
>>   3 :: Integer
>>
>> Roman
>
>
>
> Thanks Roman -- that helps.
> And yet the ghci error is much more obscure than the gofer error:
>
> --- contents of .ghci ---
> :set -XRebindableSyntax
> let fromInteger = id
> ------ ghci session -----
> $ ghci
> GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
>
> Loading package ghc-prim ... linking ... done.
> Loading package integer-gmp ... linking ... done.
> Loading package base ... linking ... done.
> Prelude> :t 5
> 5 :: Integer
> Prelude> :t [[1,2],3]
>
> <interactive>:1:8:
>     Couldn't match expected type `[Integer]' with actual type `Integer'
>     Expected type: Integer -> [Integer]
>       Actual type: Integer -> Integer
>     In the expression: 3
>     In the expression: [[1, 2], 3]
>
>
> ----- The same in gofer -----
> Gofer session for:
> pustd.pre
> ? :t [[1,2],3]
>
>
> ERROR: Type error in list
> *** expression     : [[1,2],3]
>
> *** term           : 3
> *** type           : Int
> *** does not match : [Int]
> --------------
> So the error is occurring at the point of the fromInteger (= id) but the
> message does not indicate that
>
> --
> http://www.the-magus.in
> http://blog.languager.org
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe <at> haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
Kim-Ee Yeoh | 27 Dec 15:56 2012

Re: Non polymorphic numerals option -- avoiding type classes

Hi David, it looks like Rustom's aware that haskell's not lisp. What he really wants methinks is a way to suppress type classes altogether! That or a NoOverloadedNumerals extension.


-- Kim-Ee


On Thu, Dec 27, 2012 at 4:03 PM, David Virebayre <dav.vire+haskell <at> gmail.com> wrote:
Prelude> :t [[1,2],3]

you have a list with 2 elements:
- [1,2]
- 3
the type of [1,2] is [Integer]
the type of 3 is Integer

But all elements in a list must have the same type.





2012/12/27 Rustom Mody <rustompmody <at> gmail.com>:
>
>
> On Thu, Dec 27, 2012 at 1:48 AM, Roman Cheplyaka <roma <at> ro-che.info> wrote:
>>
>> * Rustom Mody <rustompmody <at> gmail.com> [2012-12-26 20:12:17+0530]
>> > So is there any set of flags to make haskell literals less polymorphic?
>>
>> Yes, there is!
>>
>>   % ghci -XRebindableSyntax
>>   GHCi, version 7.6.1: http://www.haskell.org/ghc/  :? for help
>>   Loading package ghc-prim ... linking ... done.
>>   Loading package integer-gmp ... linking ... done.
>>   Loading package base ... linking ... done.
>>   > import Prelude hiding (fromInteger)
>>   Prelude> let fromInteger = id
>>   Prelude> :t 3
>>   3 :: Integer
>>
>> Roman
>
>
>
> Thanks Roman -- that helps.
> And yet the ghci error is much more obscure than the gofer error:
>
> --- contents of .ghci ---
> :set -XRebindableSyntax
> let fromInteger = id
> ------ ghci session -----
> $ ghci
> GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
>
> Loading package ghc-prim ... linking ... done.
> Loading package integer-gmp ... linking ... done.
> Loading package base ... linking ... done.
> Prelude> :t 5
> 5 :: Integer
> Prelude> :t [[1,2],3]
>
> <interactive>:1:8:
>     Couldn't match expected type `[Integer]' with actual type `Integer'
>     Expected type: Integer -> [Integer]
>       Actual type: Integer -> Integer
>     In the expression: 3
>     In the expression: [[1, 2], 3]
>
>
> ----- The same in gofer -----
> Gofer session for:
> pustd.pre
> ? :t [[1,2],3]
>
>
> ERROR: Type error in list
> *** expression     : [[1,2],3]
>
> *** term           : 3
> *** type           : Int
> *** does not match : [Int]
> --------------
> So the error is occurring at the point of the fromInteger (= id) but the
> message does not indicate that
>
> --
> http://www.the-magus.in
> http://blog.languager.org
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe <at> haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Rustom Mody | 27 Dec 17:48 2012
Picon

Re: Non polymorphic numerals option -- avoiding type classes

On Thu, Dec 27, 2012 at 8:26 PM, Kim-Ee Yeoh <ky3 <at> atamo.com> wrote:

Hi David, it looks like Rustom's aware that haskell's not lisp. What he really wants methinks is a way to suppress type classes altogether! That or a NoOverloadedNumerals extension.

-- Kim-Ee


I'm not really sure about that... Look!

ghci with default startup
--------------------
$ ghci
GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :t [[1,2],3]
[[1,2],3] :: (Num [t], Num t) => [[t]]

So it would appear that ghci is giving a well-typing for [[1,2], 3].
But is it?

Prelude> [[1,2],3]

<interactive>:3:8:
    No instance for (Num [t0])
      arising from the literal `3'
    Possible fix: add an instance declaration for (Num [t0])
    In the expression: 3
    In the expression: [[1, 2], 3]
    In an equation for `it': it = [[1, 2], 3]
-------------------
So is it well-typed in ghci or not??

And  now we add Roman's suggestions...
$ cat .ghci
:set -XRebindableSyntax
let fromInteger = id

And run ghci again

$ ghci
GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :t [[1,2],3]

<interactive>:1:8:
    Couldn't match expected type `[Integer]' with actual type `Integer'
    Expected type: Integer -> [Integer]
      Actual type: Integer -> Integer
    In the expression: 3
    In the expression: [[1, 2], 3]
Prelude> [[1,2],3]

<interactive>:3:8:
    Couldn't match expected type `[Integer]' with actual type `Integer'
    Expected type: Integer -> [Integer]
      Actual type: Integer -> Integer
    In the expression: 3
    In the expression: [[1, 2], 3]
Prelude>

So far so good -- when an expression is type-wrong, its 'wrongness' is the same irrespective of whether I ask for its type or evaluate it.

But now we are in for new surprises:  Try out
f x y = x / y
Prelude> :l f
[1 of 1] Compiling Main             ( f.hs, interpreted )

f.hs:1:11: Not in scope: `/'
Failed, modules loaded: none.
Prelude> (/)

Oh is it that now integer literals are just plain Integers and cant be divided using '/' ??

So lets replace '/' with '+'
f.hs:1:11: Not in scope: `+'

And now I am at my wits end!
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
satvik chauhan | 27 Dec 18:18 2012
Picon

Re: Non polymorphic numerals option -- avoiding type classes

I don't know about the RebindableSyntax extension.  But 

Prelude> :t [[1,2],3]
[[1,2],3] :: (Num [t], Num t) => [[t]]

The above only says that is is possible to have a list like [[1,2],3] if you have for a Num t, [t] is also an instance of Num. But it doesn't guarantee the existence of such an instance. When you actually execute the code then you see that no such instance exists by default. 

-Satvik

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Roman Cheplyaka | 27 Dec 18:22 2012

Re: Non polymorphic numerals option -- avoiding type classes

* Rustom Mody <rustompmody <at> gmail.com> [2012-12-27 22:18:15+0530]
> But now we are in for new surprises:  Try out
> f x y = x / y
> Prelude> :l f
> [1 of 1] Compiling Main             ( f.hs, interpreted )
> 
> f.hs:1:11: Not in scope: `/'
> Failed, modules loaded: none.
> Prelude> (/)

It's because RebindableSyntax implies NoImplicitPrelude. This is not an
issue if you only work in the interpreter (you can put "import Prelude
hiding (fromInteger)" in .ghci), but you'd also need to put that into
every source file that you wish to load.

An alternative would be to create your own Prelude (or use an existing
one, like [1]) and use it instead of the one defined in base (by hiding
base and exposing a different package).

[1]: http://hackage.haskell.org/packages/archive/simpleprelude/1.0.1.3/doc/html/Prelude.html

Roman
Roman Cheplyaka | 27 Dec 18:28 2012

Re: Non polymorphic numerals option -- avoiding type classes

Forgot to say: if you go the first route, you'll also need to define your
fromInteger in every module — the one from .ghci won't be in scope.

You can define

  module MyPrelude (module Prelude, fromInteger) where

  import Prelude hiding (fromInteger)

  fromInteger = id

and import it instead.

* Roman Cheplyaka <roma <at> ro-che.info> [2012-12-27 19:22:53+0200]
> * Rustom Mody <rustompmody <at> gmail.com> [2012-12-27 22:18:15+0530]
> > But now we are in for new surprises:  Try out
> > f x y = x / y
> > Prelude> :l f
> > [1 of 1] Compiling Main             ( f.hs, interpreted )
> > 
> > f.hs:1:11: Not in scope: `/'
> > Failed, modules loaded: none.
> > Prelude> (/)
> 
> It's because RebindableSyntax implies NoImplicitPrelude. This is not an
> issue if you only work in the interpreter (you can put "import Prelude
> hiding (fromInteger)" in .ghci), but you'd also need to put that into
> every source file that you wish to load.
> 
> An alternative would be to create your own Prelude (or use an existing
> one, like [1]) and use it instead of the one defined in base (by hiding
> base and exposing a different package).
> 
> [1]: http://hackage.haskell.org/packages/archive/simpleprelude/1.0.1.3/doc/html/Prelude.html
> 
> Roman

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Kim-Ee Yeoh | 27 Dec 23:43 2012

Re: Non polymorphic numerals option -- avoiding type classes

On Thu, Dec 27, 2012 at 11:48 PM, Rustom Mody <rustompmody <at> gmail.com> wrote:
> On Thu, Dec 27, 2012 at 8:26 PM, Kim-Ee Yeoh <ky3 <at> atamo.com> wrote:
>> What he really wants methinks is a way to suppress type classes altogether! That or a NoOverloadedNumerals extension.
>
> I'm not really sure about that... Look!

>
> Prelude> :t [[1,2],3]
> [[1,2],3] :: (Num [t], Num t) => [[t]]

As Satvik explained, well-typed does not imply instantiable. And with constraints, not instantiable /does/ imply not evaluable!

> :set -XRebindableSyntax
> let fromInteger = id
> Prelude> :t [[1,2],3]
>
>     Couldn't match expected type `[Integer]' with actual type `Integer'
>     Expected type: Integer -> [Integer]
>       Actual type: Integer -> Integer
>     In the expression: 3
>     In the expression: [[1, 2], 3]

You can see overloaded numerals at work again via the hidden hand of fromInteger. 

Presumably some imaginary NoOverloadedNumerals extension would thoroughly purge its presence.

-- Kim-Ee


On Thu, Dec 27, 2012 at 11:48 PM, Rustom Mody <rustompmody <at> gmail.com> wrote:
>
> On Thu, Dec 27, 2012 at 8:26 PM, Kim-Ee Yeoh <ky3 <at> atamo.com> wrote:
>>
>> Hi David, it looks like Rustom's aware that haskell's not lisp. What he really wants methinks is a way to suppress type classes altogether! That or a NoOverloadedNumerals extension.
>>
>> -- Kim-Ee
>>
>
> I'm not really sure about that... Look!
>
> ghci with default startup
> --------------------
>
> $ ghci
> GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
> Loading package ghc-prim ... linking ... done.
> Loading package integer-gmp ... linking ... done.
> Loading package base ... linking ... done.
> Prelude> :t [[1,2],3]
> [[1,2],3] :: (Num [t], Num t) => [[t]]
>
> So it would appear that ghci is giving a well-typing for [[1,2], 3].
> But is it?
>
> Prelude> [[1,2],3]
>
> <interactive>:3:8:
>
>     No instance for (Num [t0])
>       arising from the literal `3'
>
>     Possible fix: add an instance declaration for (Num [t0])
>     In the expression: 3
>     In the expression: [[1, 2], 3]
>     In an equation for `it': it = [[1, 2], 3]
> -------------------
> So is it well-typed in ghci or not??
>
> And  now we add Roman's suggestions...
> $ cat .ghci
>
> :set -XRebindableSyntax
> let fromInteger = id
>
> And run ghci again
>
>
> $ ghci
> GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
> Loading package ghc-prim ... linking ... done.
> Loading package integer-gmp ... linking ... done.
> Loading package base ... linking ... done.
> Prelude> :t [[1,2],3]
>
> <interactive>:1:8:
>     Couldn't match expected type `[Integer]' with actual type `Integer'
>     Expected type: Integer -> [Integer]
>       Actual type: Integer -> Integer
>     In the expression: 3
>     In the expression: [[1, 2], 3]
> Prelude> [[1,2],3]
>
> <interactive>:3:8:
>
>     Couldn't match expected type `[Integer]' with actual type `Integer'
>     Expected type: Integer -> [Integer]
>       Actual type: Integer -> Integer
>     In the expression: 3
>     In the expression: [[1, 2], 3]
> Prelude>
>
> So far so good -- when an expression is type-wrong, its 'wrongness' is the same irrespective of whether I ask for its type or evaluate it.
>
> But now we are in for new surprises:  Try out
> f x y = x / y
> Prelude> :l f
> [1 of 1] Compiling Main             ( f.hs, interpreted )
>
> f.hs:1:11: Not in scope: `/'
> Failed, modules loaded: none.
> Prelude> (/)
>
> Oh is it that now integer literals are just plain Integers and cant be divided using '/' ??
>
> So lets replace '/' with '+'
> f.hs:1:11: Not in scope: `+'
>
> And now I am at my wits end!

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Gmane