Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Re: Why is type "Integer -> Integer" and not "(Num a) => a
-> a"? (Chadda? Fouch?)
2. Re: Why is type "Integer -> Integer" and not "(Num a) => a
-> a"? (Shawn Willden)
3. Re: Why is type "Integer -> Integer" and not "(Num a) => a
-> a"? (Felipe Lessa)
4. Re: Why is type "Integer -> Integer" and not "(Num a) => a
-> a"? (Nathan M. Holden)
5. Re: Why is type "Integer -> Integer" and not "(Num a) => a
-> a"? (Chadda? Fouch?)
6. Re: maybe this could be improved? (Patrick LeBoutillier)
7. Re: maybe this could be improved? (Michael Mossey)
8. Re: maybe this could be improved? (Patrick LeBoutillier)
----------------------------------------------------------------------
Message: 1
Date: Thu, 12 Nov 2009 10:04:53 +0100
From: Chadda? Fouch? <[email protected]>
Subject: Re: [Haskell-beginners] Why is type "Integer -> Integer" and
not "(Num a) => a -> a"?
To: Dag Hovland <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=UTF-8
On Thu, Nov 12, 2009 at 9:37 AM, Dag Hovland <[email protected]> wrote:
> Hi!
>
> I have a problem with understanding some types given by ghc and hugs.
> The file loaded is:
>
> f1 = \x -> x * 2
> f2 x = x * 2
>
> After they are loaded I get the following from ghci
>
> *Main> :t f1
> f1 :: Integer -> Integer
> *Main> :t f2
> f2 :: (Num a) => a -> a
> *Main> :t \x -> x * 2
> \x -> x * 2 :: (Num a) => a -> a
This is called the monomorphism restriction, it's a rule that state a
binding _without_parameters_ shall be inferred of a monomorphic type
unless an explicit signature is given. There are several reasons for
it, some of efficiency (polymorphism has a cost) and some of a more
technical nature, refer to the Haskell Report for a more detailed
explanation.
Some Haskellers think this restriction is no longer required, that GHC
is now often intelligent enough to alleviate the cost of polymorphism,
that the technical reasons are not really all that pertinent and that
the default should be to infer the more general type in all case
rather than confuse beginners and oblige experts to put explicit
signatures. It is already possible to deactivate the restriction by
using the -XNoMonomorphismRestriction argument (or putting the
equivalent language pragma in the code itself or in the cabal
description file) and making this the default is discussed for
Haskell' (the future standard for Haskell).
In the meantime, it is a good idea to put ":set
-XNoMonomorphismRestriction" in your .ghci file since most usage of
GHCi would only hit the disadvantages of this rule and reap no
benefits from it.
--
Jedaï
------------------------------
Message: 2
Date: Thu, 12 Nov 2009 02:06:00 -0700
From: Shawn Willden <[email protected]>
Subject: Re: [Haskell-beginners] Why is type "Integer -> Integer" and
not "(Num a) => a -> a"?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
On Thursday 12 November 2009 01:45:08 am Joe Fredette wrote:
> My guess is that, defining in GHCi
>
> > let f x = x * 2
> > let g = \x -> x * 2
>
> the former doesn't default to anything (it just does inference) since
> it's a function definition, and the latter defaults the '2' to an
> Integer because it's a value -- or some suitable analog of that
> situation.
Hmm. Would that also explain this?
Prelude> let f1 x = x * 2
Prelude> :type f1
f1 :: (Num a) => a -> a
Prelude> let f2 = \x -> f1 x
Prelude> :type f2
f2 :: Integer -> Integer
Shawn.
------------------------------
Message: 3
Date: Thu, 12 Nov 2009 08:40:49 -0200
From: Felipe Lessa <[email protected]>
Subject: Re: [Haskell-beginners] Why is type "Integer -> Integer" and
not "(Num a) => a -> a"?
To: Shawn Willden <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=UTF-8
On Thu, Nov 12, 2009 at 7:06 AM, Shawn Willden
<[email protected]> wrote:
> Hmm. Â Would that also explain this?
>
> Prelude> let f1 x = x * 2
> Prelude> :type f1
> f1 :: (Num a) => a -> a
> Prelude> let f2 = \x -> f1 x
> Prelude> :type f2
> f2 :: Integer -> Integer
Yes, that's the same monomorphism restriction. Also, note that you
are defaulting to Integer here:
Prelude> :s -Wall
Prelude> let f1 x = x * 2
Prelude> :t f1
f1 :: (Num a) => a -> a
Prelude> let f2 = \x -> f1 x
<interactive>:1:15:
Warning: Defaulting the following constraint(s) to type `Integer'
`Num a' arising from a use of `f1' at <interactive>:1:15-18
In the expression: f1 x
In the expression: \ x -> f1 x
In the definition of `f2': f2 = \ x -> f1 x
Prelude> let f3 :: Int -> Int; f3 = \x -> f1 x
Prelude> let f4 :: Num a => a -> a; f4 = \x -> f1 x
I find -Wall very useful. Relatively few times it gets annoying.
HTH,
--
Felipe.
------------------------------
Message: 4
Date: Thu, 12 Nov 2009 11:40:35 -0500
From: "Nathan M. Holden" <[email protected]>
Subject: Re: [Haskell-beginners] Why is type "Integer -> Integer" and
not "(Num a) => a -> a"?
To: [email protected]
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: Text/Plain; charset="us-ascii"
This is just a theory, but in my (limited) experience, GHCi is willing to
guess at the type of values, where at functions (explicitly or implicitly
typed) it can't guess.
In your original function, it multiplied a number (Num a) => a by an Int,
therefor it must be Int -> Int (because you can't multiply a Double by an Int,
don't be crazy.
In the new function, though, it can infer the type of the 2, and therefor it
can infer it to whatever numerical type you send it.
I've run into this problem a few times, but for whatever reason I can't get
myself to fall into any of the usual ways I walk blindly into these sorts of
problems this time.
------------------------------
Message: 5
Date: Thu, 12 Nov 2009 18:44:59 +0100
From: Chadda? Fouch? <[email protected]>
Subject: Re: [Haskell-beginners] Why is type "Integer -> Integer" and
not "(Num a) => a -> a"?
To: "Nathan M. Holden" <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=UTF-8
On Thu, Nov 12, 2009 at 5:40 PM, Nathan M. Holden
<[email protected]> wrote:
> This is just a theory, but in my (limited) experience, GHCi is willing to
> guess at the type of values, where at functions (explicitly or implicitly
> typed) it can't guess.
>
> In your original function, it multiplied a number (Num a) => a by an Int,
> therefor it must be Int -> Int (because you can't multiply a Double by an Int,
> don't be crazy.
That is not the problem : as the rest of your message acknowledge 2 is
not an Int, it is of type (Num a) => a. The issue rest squarely with
the fact that the binding f1 don't have parameter expressed on the
left side of the "=", thus the monomorphism restriction kicks in (as
alluded, probably, by your first paragraph) and GHC has to use the
defaulting rules to find a monomorphic type for f1.
--
Jedaï
------------------------------
Message: 6
Date: Thu, 12 Nov 2009 14:05:58 -0500
From: Patrick LeBoutillier <[email protected]>
Subject: Re: [Haskell-beginners] maybe this could be improved?
To: Michael P Mossey <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Michael,
Here's my stab at it, not sure if it's really better though:
findClosestPitch :: SampleMap -> Pitch -> ErrorT String Identity Pitch
findClosestPitch samples inPitch = do
when (M.null samples) $ throwError "Was given empty sample table."
case M.splitLookup inPitch samples of
(_, Just _, _) -> return inPitch
(ml, _, mh) -> return $ approxPitch ml mh
where
approxPitch ml mh | M.null ml = fst . M.findMin $ mh
approxPitch ml mh | M.null mh = fst . M.findMax $ ml
approxPitch ml mh = closest (fst . M.findMax $ ml)
(fst . M.findMin $ mh)
where closest a b = min (inPitch - a) (b - inPitch)
I tried to separate the approximation part from the rest of the code,
and used a bit of deduction to eliminate (hopefully correctly...) some
of the testing conditions.
Anyways, I had fun doing working on this, and I learned a bit about
computerized music as well!
Thanks,
Patrick
On Wed, Nov 11, 2009 at 9:15 PM, Michael P Mossey
<[email protected]> wrote:
> Patrick LeBoutillier wrote:
>>
>> Michael,
>>
>> Your code is interesting and I'd like to run it, but I'm not to
>> familiar with Maps and Monad transformers.
>> Could you provide a function to create a SampleMap and a way to test
>> it from ghci?
>>
>
> Sure,
>
>
> import Control.Monad.Identity
> import Control.Monad.Error
> import Control.Monad
> import qualified Data.Map as M
>
> type Pitch = Int
> type Sample = String
> type SampleMap = M.Map Pitch Sample
>
>
> -- Given a SampleMap and a Pitch, find the Pitch in the SampleMap
> -- which is closest to the supplied Pitch and return that. Also
> -- handle case of null map by throwing an error.
> findClosestPitch :: SampleMap -> Pitch -> ErrorT String Identity Pitch
> findClosestPitch samples inPitch = do
> when (M.null samples) $ throwError "Was given empty sample table."
> case M.splitLookup inPitch samples of
> (_,Just _,_ ) -> return inPitch
> (m1,_ ,m2) | (M.null m1) && not (M.null m2) -> case1
> | not (M.null m1) && (M.null m2) -> case2
> | otherwise -> case3
> where case1 = return . fst . M.findMin $ m2
> case2 = return . fst . M.findMax $ m1
> case3 = return $ closest (fst . M.findMax $ m1)
> (fst . M.findMin $ m2)
> closest a b = if abs (a - inPitch) < abs (b - inPitch)
> then a
> else b
>
>
> testMap1 = M.fromList [ (1,"sample1")
> , (5,"sample2")
> , (9,"sample3") ]
>
> -- testMap2 ==> Right 1
> testMap2 = runIdentity $ runErrorT $ findClosestPitch testMap1 2
>
>
> -- testMap3 ==> Right 5
> testMap3 = runIdentity $ runErrorT $ findClosestPitch testMap1 5
>
> -- testMap4 ==> Left "Was given empty sample table."
> testMap4 = runIdentity $ runErrorT $ findClosestPitch M.empty 5
>
>
>
>
>
--
=====================
Patrick LeBoutillier
Rosemère, Québec, Canada
------------------------------
Message: 7
Date: Thu, 12 Nov 2009 14:31:29 -0800
From: Michael Mossey <[email protected]>
Subject: Re: [Haskell-beginners] maybe this could be improved?
To: Patrick LeBoutillier <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Hi, Thanks for your help and it looks like you identified some conditions
that could be removed. There is one change necessary, I think.
closest a b = if (inPitch - a) < (b - inPitch) then a else b
Patrick LeBoutillier wrote:
> Michael,
>
> Here's my stab at it, not sure if it's really better though:
>
>
> findClosestPitch :: SampleMap -> Pitch -> ErrorT String Identity Pitch
> findClosestPitch samples inPitch = do
> when (M.null samples) $ throwError "Was given empty sample table."
> case M.splitLookup inPitch samples of
> (_, Just _, _) -> return inPitch
> (ml, _, mh) -> return $ approxPitch ml mh
> where
> approxPitch ml mh | M.null ml = fst . M.findMin $ mh
> approxPitch ml mh | M.null mh = fst . M.findMax $ ml
> approxPitch ml mh = closest (fst . M.findMax $ ml)
> (fst . M.findMin $ mh)
> where closest a b = min (inPitch - a) (b - inPitch)
>
>
> I tried to separate the approximation part from the rest of the code,
> and used a bit of deduction to eliminate (hopefully correctly...) some
> of the testing conditions.
> Anyways, I had fun doing working on this, and I learned a bit about
> computerized music as well!
>
>
> Thanks,
>
> Patrick
>
>
>
------------------------------
Message: 8
Date: Thu, 12 Nov 2009 19:06:23 -0500
From: Patrick LeBoutillier <[email protected]>
Subject: Re: [Haskell-beginners] maybe this could be improved?
To: Michael Mossey <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
On Thu, Nov 12, 2009 at 5:31 PM, Michael Mossey <[email protected]> wrote:
> Hi, Thanks for your help and it looks like you identified some conditions
> that could be removed. There is one change necessary, I think.
>
> closest a b = if (inPitch - a) < (b - inPitch) then a else b
Yes, of course. I just happens that in the test code (testMap2) it
gives the same answer...
Patrick
>
> Patrick LeBoutillier wrote:
>>
>> Michael,
>>
>> Here's my stab at it, not sure if it's really better though:
>>
>>
>> findClosestPitch :: SampleMap -> Pitch -> ErrorT String Identity Pitch
>> findClosestPitch samples inPitch = do
>> when (M.null samples) $ throwError "Was given empty sample table."
>> case M.splitLookup inPitch samples of
>> (_, Just _, _) -> return inPitch
>> (ml, _, mh) -> return $ approxPitch ml mh
>> where
>> approxPitch ml mh | M.null ml = fst . M.findMin $ mh
>> approxPitch ml mh | M.null mh = fst . M.findMax $ ml
>> approxPitch ml mh = closest (fst . M.findMax $ ml)
>> (fst . M.findMin $ mh)
>> where closest a b = min (inPitch - a) (b - inPitch)
>>
>>
>> I tried to separate the approximation part from the rest of the code,
>> and used a bit of deduction to eliminate (hopefully correctly...) some
>> of the testing conditions.
>> Anyways, I had fun doing working on this, and I learned a bit about
>> computerized music as well!
>>
>>
>> Thanks,
>>
>> Patrick
>>
>>
>>
>
--
=====================
Patrick LeBoutillier
Rosemère, Québec, Canada
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 17, Issue 15
*****************************************