Multiple parameters vs anonymous syntax

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Multiple parameters vs anonymous syntax

Wink Saville
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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

anon.hs (184 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Multiple parameters vs anonymous syntax

David McBride
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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners



_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Multiple parameters vs anonymous syntax

Wink Saville
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:



On Tue, Oct 17, 2017 at 10:53 AM David McBride <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners