Thank you, my head's spinning just starting to read [1] :)

BTW, you led me to find the answer to why ghci was different in the
interactive mode vs loading. I discovered there are two sets of options
used for ghci which are controlled by ":set" and ":seti", [2]. And in the
interactive mode we see -XNoMonomorphismRestriction is in effect:

Prelude> :seti
base language is: Haskell2010
with the following modifiers:
  -XExtendedDefaultRules
  -XNoMonomorphismRestriction
  -XNondecreasingIndentation
GHCi-specific dynamic flag settings:
other dynamic, non-language, flag settings:
  -fimplicit-import-qualified
warning settings:


But it's not in the "non-interactive" mode:

Prelude> :set
options currently set: none.
base language is: Haskell2010
with the following modifiers:
  -XNondecreasingIndentation
GHCi-specific dynamic flag settings:
other dynamic, non-language, flag settings:
  -fimplicit-import-qualified
warning settings:

[1]: https://wiki.haskell.org/Monomorphism_restriction
[2]: https://downloads.haskell.org/~ghc/7.8.4/docs/html/users_guide/ghci-set.html


On Tue, Oct 17, 2017 at 10:53 AM David McBride <toad3k@gmail.com> wrote:
It is because of NoMomomorphismRestriction

>let mTh4 = \x -> \y -> \z -> x * y * z

>:t mTh4
mTh4 :: Integer -> Integer -> Integer -> Integer
>:set -XNoMonomorphismRestriction
>let mTh4 = \x -> \y -> \z -> x * y * z

>:t mTh4
mTh4 :: Num a => a -> a -> a -> a

I'm not going into it too deeply, as it is somewhat involved and you can read about it but I believe when a function "takes no arguments", it is allowed to specialize polymorphic variables to defaults, and due to the Num constraint it chooses Integer.

On Tue, Oct 17, 2017 at 1:28 PM, Wink Saville <wink@saville.com> wrote:
I'm going through "Haskell Programming from first principles" and in section 7.3 Anonymous Functions there is an exercise on converting multiple parameters to anonymous functions, and it asks:

1. Which (two or more) of the following are equivalent?

mTh1 x y z = x * y * z
mTh2 x y = \z -> x * y * z
mTh3 x = \y -> \z -> x * y * z
mTh4 = \x -> \y -> \z -> x * y * z

So I created a file, anon.hs (attached):

module Anon where

mTh1 x y z = x * y * z
mTh2 x y = \z -> x * y * z
mTh3 x = \y -> \z -> x * y * z
mTh4 = \x -> \y -> \z -> x * y * z

I load that into ghci and check the function types:

$ ghci anon.hs 
GHCi, version 8.2.1: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Anon             ( anon.hs, interpreted )
Ok, 1 module loaded.
*Anon> :t mTh1
mTh1 :: Num a => a -> a -> a -> a
*Anon> :t mTh2
mTh2 :: Num a => a -> a -> a -> a
*Anon> :t mTh3
mTh3 :: Num a => a -> a -> a -> a
*Anon> :t mTh4
mTh4 :: Integer -> Integer -> Integer -> Integer

Why is mTh4 different from the rest?


On the flip side If I enter "mTh4 = \x -> \y -> \z -> x * y * z" directly in ghci command line then it has same type as the others:

$ ghci
GHCi, version 8.2.1: http://www.haskell.org/ghc/  :? for help
Prelude> mTh4 = \x -> \y -> \z -> x * y * z
Prelude> :t mTh4
mTh4 :: Num a => a -> a -> a -> a


-- Wink


_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners