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:  Complex list manipulation (Daniel Fischer)
   2. Re:  What is the best practice for code] (Austin Wood)
   3. Re:  maybe this could be improved? (Darrin Thompson)
   4. Re:  maybe this could be improved? (Patrick LeBoutillier)
   5. Re:  maybe this could be improved? (Michael P Mossey)
   6.  Why is type "Integer -> Integer" and not "(Num   a) => a ->
      a"? (Dag Hovland)
   7. Re:  Why is type "Integer -> Integer" and not     "(Num a) => a
      -> a"? (Joe Fredette)


----------------------------------------------------------------------

Message: 1
Date: Tue, 10 Nov 2009 22:45:16 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Complex list manipulation
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="iso-8859-1"

Am Dienstag 10 November 2009 22:09:36 schrieb legajid:
> Hello,
> i'm trying to manipulate lists with a "complex" (two-level) structure :
> a list containing tuples, containing a list containing tuples.
> The object is to find a specific value according to 2 criterias.
>
> Here is my code
>
> tabmul= [ ( a, [ ( n, n*a ) | n <- [1..9] ] ) | a <- [2,3,4] ]
>
> {- gives the following list
> [
>  (2, [(1,2), (2,4), ....(9,18)]),
>  (3, [(1,3), (2,6), ....(9,27)]),
>  (4, [(1,4), (2,8), ....(9,36)])
> ]
> -}
>
>
> {-  Get the result for a=3 and n=5  -}
>
> -- select level 1 tuple for a=3
> s1_flt (x,_) = (x==3)
> s1=filter (s1_flt) tabmul -- get the list  [(3, [(), () .......])]

filter ((== 3) . fst) tabmul

> s1_liste =head(s1)        -- get the tuple (3, [.....])

You might want to use

Data.List.lookup :: (Eq a) => a -> [(a,b)] -> Maybe b

lookup 3 tabmul 
~> Just [(1,3),...]

>
> -- extract the level 2 list of tuples
> s1_tup (x,y)=y

That's Prelude.snd (fst (a,b) = a; snd (a,b) = b)

>
> -- then tuple for n=5
> s1_flt2 (x, y) = x==5

(== 5) . fst

> s1_soltup = filter (s1_flt2) (s1_tup s1_liste)  -- [(3,15)]
>
> --finally result for 3 * 5
> s1_sol1 (x, y)= y
> s1_sol = s1_sol1 (head s1_soltup)

lookup 3 tabmul >>= lookup 5

or

do listetrois <- lookup 3 tabmul
   lookup 5 listetrois

~> Just 15

>
>
> Perhaps the structure is not the most efficient for this example, but it
> may simulate records in a database.
> Getting the result seems really hard.
> Do you know a shorter way to implement this search?
> It probably would be simpler when i had triples (a, n ,a*n) ?

Not necessarily, there are 

fst :: (a,b) -> a

and

snd :: (a,b) -> b

in the Prelude, but not the analogous functions for triples or larger tuples.

head . filter ((== val) . fst)

is pretty simple, but if you want to use association lists as maps, lookup is 
even more 
handy.

>
> Another question : the values of criterias are hard-coded. What if i
> would like to type in s1_sol 3 5; how to put these parameters in the
> expressions for filters; the filters must get the parameters of the
> function, in other words the function should return or generate filters ?

résultat x y = lookup x tabmul >>= lookup y

résultat x y = do
    liste <- lookup x tabmul
    lookup y liste

résultat x y = head . filter ((== y) . fst) . snd . filter ((== x) . fst) $ 
tabmul

In my book, the first two are clear winners.

>
> Thanks for helping
> Didier.




------------------------------

Message: 2
Date: Wed, 11 Nov 2009 11:50:03 +1100
From: Austin Wood <[email protected]>
Subject: Re: [Haskell-beginners] What is the best practice for code]
To: legajid <[email protected]>
Cc: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Nov 10, 2009 at 8:46 AM, legajid <[email protected]> wrote:
> i wanted to write a program that searches for all combinations of some
> numbers, the sum of which is a given value.
> So, i started writing my program, creating a function for each separate
> phase : creating list of triples, selecting valuable ones, filtering the
> result.
>
> Looking at my code, i've reduced it several ways; the last version holds on
> one single line of code.
>
> Please, from the 3 versions i established, which one is " better"? What are
> the criterias of a "good" code ?
> What about using many anonymous functions?
> I think there are other solutions than those i propose.

It could be done using do;

import Control.Monad

numbers = [9,8..1]
f = do x <- numbers
       y <- numbers
       z <- numbers
       guard (y < x && z < y)
       guard (x+y+z == 19)
       return [x,y,z]


------------------------------

Message: 3
Date: Wed, 11 Nov 2009 11:06:27 -0500
From: Darrin Thompson <[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 Sat, Nov 7, 2009 at 12:44 PM, Michael Mossey <[email protected]> wrote:
>      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
>

I'd try writing quickcheck properties for these cases.

That is a really complicated function. It strikes me that a lot of
those cases need less available in their scopes than they have. You
could force that by breaking the cases and closest into individual
functions. Then you could write properties for them. Then you are left
with only one complex function determining which case you need.
Possibly you could return the case directly?

Anyway, that's not as helpful as telling you that you just reinvented
a 4 and a half gainer comonad or whatever but if you start cutting
this thing up you might notice a structure you already know.

--
Darrin


------------------------------

Message: 4
Date: Wed, 11 Nov 2009 20:52:01 -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

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?

Thanks,

Patrick

On Sat, Nov 7, 2009 at 12:44 PM, Michael Mossey <[email protected]> wrote:
> I've got some code which could be made simpler, I hope. the problem is
> this: I am
> implementing a software sampling synthesizer. For a given musical
> instrument, like piano, there are sound samples in memory. One purchases
> or creates sample sets. To
> save time money & resources, most sample sets are not complete---they have
> samples for only some of the pitches. Perhaps every third pitch has a
> sample. For the software to produce the sound for a non-included pitch,
> the software finds the closest included sample and plays it back slightly
> slower/faster to get the target pitch.
>
> That leads to the following code. Any ideas for improvement are welcome.
> The problem is that there are many cases to check: an empty map? the
> requested pitch less than all available pitches, greater than all
> available, or somewhere between? I am specifically writing this to run in
> O( log n) time. (It would be simpler as O(n).) This particular algorithm
> probably doesn't need to run in O(log n) time, but I want to do it as an
> educational experience---I will have other applications that need to use
> Map in O(log n) time.
>
> 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
>
>
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>



-- 
=====================
Patrick LeBoutillier
Rosemère, Québec, Canada


------------------------------

Message: 5
Date: Wed, 11 Nov 2009 18:15:36 -0800
From: Michael P 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

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






------------------------------

Message: 6
Date: Thu, 12 Nov 2009 09:37:28 +0100
From: Dag Hovland <[email protected]>
Subject: [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"

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


I do not understand why f1 is given Integer -> Integer as a type and not
the polymorphic (Num a) => a -> a. I believed that f1, f2 and the lambda
expression should all have the same type. Similar output to that above
is given by Hugs.

Thanks,

Dag Hovland
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3880 bytes
Desc: S/MIME Cryptographic Signature
Url : 
http://www.haskell.org/pipermail/beginners/attachments/20091112/a88251b0/smime-0001.bin

------------------------------

Message: 7
Date: Thu, 12 Nov 2009 03:45:08 -0500
From: Joe Fredette <[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=US-ASCII; format=flowed; delsp=yes

Hi!

That's very weird, I don't have a good answer (and fortunately there  
are far smarter people on this list who will have a better answer...)  
but my instincts say it has to do with defaulting.

When GHC sees a literal digit, it tries to guess what it's type should  
be, first via inference, but if that returns a polymorphic type (like  
`Num a => a` or something) it will "default" to a particular type, for  
literal whole positive/negative numbers, it defaults to `Integer`. 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.

What will really blow your mind, try having GHCi inspect the type of

 > :t \x -> x * 2

(the defn. of `g` w/o the let...)

Short answer, I have no idea, but I think it has to do with defaulting.

/Joe

On Nov 12, 2009, at 3:37 AM, Dag Hovland 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
>
>
> I do not understand why f1 is given Integer -> Integer as a type and  
> not
> the polymorphic (Num a) => a -> a. I believed that f1, f2 and the  
> lambda
> expression should all have the same type. Similar output to that above
> is given by Hugs.
>
> Thanks,
>
> Dag Hovland
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners



------------------------------

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 17, Issue 14
*****************************************

Reply via email to