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: Convert bits to bytes (Ertugrul Soeylemez)
2. Re: containers and extensibility, typeclasses vs. multiple
value constructors (Greg Best)
3. Re: Graham Scan exercise from Chapter 3 RWH -Spoilers. Don't
read if you want to do this exercise. (Angel de Vicente)
4. More De/Serialisation Woes (Tom Hobbs)
5. Re: containers and extensibility, typeclasses vs. multiple
value constructors (Greg)
----------------------------------------------------------------------
Message: 1
Date: Tue, 7 Sep 2010 05:41:28 +0200
From: Ertugrul Soeylemez <[email protected]>
Subject: [Haskell-beginners] Re: Convert bits to bytes
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII
Alec Benzer <[email protected]> wrote:
> What's the quickest/the best/a way of converting a series of bits into
> bytes? Ie, converting a [Bool] to a [Word8]. So if I had replicate 8 True ++
> replicate 8 False :: [Bool], it would spit out [255,0] :: [Word8].
Here is my variant:
import Data.Bits
chunks :: Int -> [a] -> [[a]]
chunks n = takeWhile (not . null) . map (take n) . iterate (drop n)
boolToDigit :: Num i => Bool -> i
boolToDigit False = 0
boolToDigit True = 1
bitsToByte :: Num i => [Bool] -> i
bitsToByte = sum . zipWith (*) (iterate (*2) 1) . map boolToDigit
bitsToBytes :: Bits i => [Bool] -> [i]
bitsToBytes x = y
where ~y@(y0:ys) = map bitsToByte . chunks (bitSize y0) $ x
It works for every binary type with a fixed length, so you can use it
with Word8, Word16, etc.
Greets,
Ertugrul
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://ertes.de/
------------------------------
Message: 2
Date: Mon, 06 Sep 2010 23:44:53 -0700
From: Greg Best <[email protected]>
Subject: Re: [Haskell-beginners] containers and extensibility,
typeclasses vs. multiple value constructors
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
Two great suggestions (attached below for context), thanks to Daniel and
Stephen, both.
Since a large part of my goal here is to learn the language, I'll probably try
both of these just to make sure I can.
>From a cultural standpoint, is there a preferred approach? Existential Types
>sits more nicely with my OO background and is a more exact interpretation of
>what I was trying to do, but is that seen as "impure" under Haskell? More
>generally, what should I keep in mind when using language extensions? Are
>Existential Types supported across implementations? Are they a likely
>candidate for adoption into the language proper? Are there performance
>implications (such as future parallelization)?
Stephen's solution is obvious now that it's been presented. I'm not planning
on using GnuPlot, I'm mucking around with the OpenGL bindings, but the point
is, I think, the same: don't make a list of of objects, make a list of
functions. In this case, they'd be more along the lines of ApplicationContext
-> IO ().
I suppose I could also create a type that contains the disembodied methods from
the various plot styles:
data PlotThunks = PlotThunks { render:: Context -> IO ()
, hitTest:: Point -> Bool
, extents:: Context ->
Rect}
then functions (perhaps a typeclass method) that build values of that type from
each of the various plot styles.
plotList :: [PlotThunks]
renderAll :: Context -> [PlotThunks] -> IO ()
renderAll context plots= mapM_ (($ context) . render) plots
Thanks again--
Greg
On Sep 6, 2010, at 6:14 AM, Daniel Fischer wrote:
> you can combine the approaches. As long as all you want to do with your
> container is rendering the contents,
>
> {-# LANGUAGE ExistentialQuantification #-}
>
> class Plot a where
> render :: a -> IO ()
> describe :: a -> String
>
> data SomePlot = forall p. Plot p => SomePlot p
>
> instance Plot SomePlot where
> render (SomePlot p) = render p
> describe (SomePlot p) = describe p
>
> gives you a class, so you can define new plot types without modifying the
> library, and a wrapper type, so you can stick plots of different types in
> the same container after wrapping them.
> Once they're wrapped, you can't use anything but the methods of the Plot
> class on them, though, so if you want to do anything else with the
> container's contents, that won't work (you can do something with an
> additional Typeable constraint).
>
> http://www.haskell.org/haskellwiki/Existential_type for more.
On Sep 6, 2010, at 7:57 AM, Stephen Tetley wrote:
> Supposing you are working with GnuPlot - one option is to make Plot a
> functional type that takes a list of some polymorphic input data and
> generates a 'GnuPlot' - where GnuPlot is a type representing output in
> the GnuPlot format.
>
> type Plot a = [a] -> GnuPlot
>
> Or if GnuPlot accepts drawing styles...
>
> type Plot a = [a] -> DrawingStyle -> GnuPlot
>
> Plots are just functions, so clearly you can define as many as you
> like and they are all the same type.
------------------------------
Message: 3
Date: Tue, 07 Sep 2010 10:15:13 +0100
From: Angel de Vicente <[email protected]>
Subject: Re: [Haskell-beginners] Graham Scan exercise from Chapter 3
RWH -Spoilers. Don't read if you want to do this exercise.
To: Michael Litchard <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Hi Michael,
On 03/09/10 01:21, Michael Litchard wrote:
> Below is my solution for the Graham Scan Algorithm.
> I tried to limit myself to information in the first three chapters
> while completing this problem.
> Now, I want to remove the explicit recursion and use more idiomatic
> Haskell. I'd like to get some advice on which functions/modules would
> be helpful in this.
This is not really what you ask for, but I thought I would point out
that you code seems to have either a bug or it doesn't implement the
Graham Scan algorithm correctly. For example, when we change the points to
[(10,0),
(10,1),(-10,1),(-10,0),(-7,0),(-10,2),(-10,3),(-4,1),(-2,2),(-12,1)]
your code gives as the solution:
*Main> main
[(10.0,0.0),(10.0,1.0),(-10.0,1.0),(-10.0,0.0),(-7.0,0.0),(10.0,1.0),(-4.0,1.0)]
while the correct solution has only 5 points
[(-10,0),(10,0),(10,1),(-10,3),(-12,1)]
Yo can see my solution to this exercise at
http://angel-de-vicente.blogspot.com/2010/06/graham-scan-in-haskell.html
Cheers,
Ángel de Vicente
>
>
> <code>
> data Direction = DStraight
> | DLeft
> | DRight
> deriving (Eq,Show)
>
> type PointXY = (Double,Double)
>
> calcTurn :: PointXY -> PointXY -> PointXY -> Direction
> calcTurn a b c
> | crossProduct == 0 = DStraight
> | crossProduct> 0 = DLeft
> | otherwise = DRight
> where crossProduct = ((fst b - fst a) * (snd c - snd a)) -
> ((snd b - snd a) * (fst c - fst a))
>
> calcDirectionList :: [PointXY] -> [Direction]
> calcDirectionList (x:y:z:zs) = (calcTurn x y z) : (calcDirectionList (y:z:zs))
> calcDirectionList _ = []
>
> sortListByY :: [PointXY] -> [PointXY]
> sortListByY [] = []
> sortListByY [a] = [a]
> sortListByY (a:as) = insert (sortListByY as)
> where insert [] = [a]
> insert (b:bs) | snd a<= snd b = a : b : bs
> | otherwise = b : insert bs
>
> sortListByCoTangent :: [PointXY] -> [PointXY]
> sortListByCoTangent [] = []
> sortListByCoTangent [a] = [a]
> sortListByCoTangent (a:as) = a : insert (sortListByCoTangent as)
> where insert :: [PointXY] -> [PointXY]
> insert [b] = [b]
> insert (b:c:cs) | (myCoTan a b)>= (myCoTan a
> c) = b : insert (c:cs)
> | otherwise
> = c : insert (b:cs)
> where myCoTan :: PointXY -> PointXY -> Double
> myCoTan p1 p2 = (fst p2 - fst p1) /
> (snd p2 - snd p1)
>
>
> createHull :: [PointXY] -> [PointXY]
> createHull (a:b:c:cs) = a : filterPoint (createHull (b:c:cs))
> where filterPoint :: [PointXY] -> [PointXY]
> filterPoint (x:y:z:zs)
> | calcTurn x y z == (DLeft) = [x] ++ [y]
> ++ [z] ++ filterPoint (zs)
> | otherwise = [x] ++ [z]
> ++ filterPoint (zs)
> filterPoint [x] = a:[x]
> filterPoint _ = []
> createHull _ = []
>
> main :: IO ()
> main = do
> let points = [(5.0,0.0),(5.0,6.0),(3.0,-4.2),(0.0,6.0)]
> print $ createHull points
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
--
http://www.iac.es/galeria/angelv/
High Performance Computing Support PostDoc
Instituto de Astrofísica de Canarias
---------------------------------------------------------------------------------------------
ADVERTENCIA: Sobre la privacidad y cumplimiento de la Ley de Protección de
Datos, acceda a http://www.iac.es/disclaimer.php
WARNING: For more information on privacy and fulfilment of the Law concerning
the Protection of Data, consult http://www.iac.es/disclaimer.php?lang=en
------------------------------
Message: 4
Date: Tue, 7 Sep 2010 10:23:21 +0100
From: Tom Hobbs <[email protected]>
Subject: [Haskell-beginners] More De/Serialisation Woes
To: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
Hi all,
Can anyone help me with some Haskell de/serialisation woes I'm encountering?
What I'm trying to do it implement a proprietary network protocol which
will enable me to talk to a network Java/Tuple Space.
Specifically, I'm trying to serialise a "TypeStructurePreamble" and send
that down the Handle (my network stream), I'm then expecting the Space to
send me a TypeStructurePreamble back again, but with different data. So I
need to de/serialise this type. I've not got all the code together yet,
because I'm trying to figure out the concepts rather than any particular
coding problem.
Here's some code I have so far;
import System.IO
(hGetLine,hClose,hPutStrLn,hSetBuffering,BufferMode(..),Handle,stdout)
import Data.Binary.Get
import qualified Data.ByteString.Lazy as L
type TypeStructurePreamble = (String,Int,[String])
-- This function I know works because it was spoon-fed to me by someone on
this list! :-)
readStrings :: Int -> Get [String]
readStrings n = replicateM n $ do
len <- getWord32be
name <- getByteString $ fromIntegral len
return $ UTF.toString name
deserialisePreamble :: Get(String, Int, [String])
deserialisePreamble = do
len <- getWord32be
typename <- getByteString $ fromIntegral len
c <- getWord32be
numFields <- getWord32be
fields <- readStrings (fromIntegral numfields)
return (typename,c,numFields)
-- not sure what this type should be
serialisePreamble :: Handle -> TypeStructurePreamble -> ??
serialisePreamble h (n,c,fs) = do
L.hPut h (encode (0xFAB1000A :: Word32))
L.hPut h (encode (length n))
L.hPut h (encode n)
L.hPut h (encode (c :: Word32))
L.hPut h (encode (length fs))
-- not sure how I would L.hPut out every
String in fs
It is my (maybe wrong) understanding that these de/serialise functions don't
actually do the work, they basically just form a description of what must be
done in order to get the work done, so I'm slightly confused on how I should
use it.
For example;
main = do
-- set up Handle called h here, I know how to do this
serialisePreamble h ("MyType",0,["field1","field2"])
--now I'm expecting to be able to read a modified
TypeStructurePreamble from h
(n,c,fs) <- deserialisePreamble -- but according to the type of
deserialisePreamble, how does the h get into it?
print "c was "+c -- can I just slot sout style statements into here?
evaluate (n,c,fs)
hClose h
return (n,c,fs)
Does this make sense? Can someone help me fill in the blanks of
serialisePreamble and main? I've read the tutorials on the Get monad which
google turns up, am I missing some really good ones? Is there some other
resource which I'm missing? I'm been thrown a lot of the Hackage
documentation on these things but (assuming I'm looking in the right place)
they seem to work more like JavaDocs and give the "what it does", rather
than the "how it should be used".
Many thanks,
Tom
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://www.haskell.org/pipermail/beginners/attachments/20100907/988fa072/attachment-0001.html
------------------------------
Message: 5
Date: Tue, 07 Sep 2010 02:39:37 -0700
From: Greg <[email protected]>
Subject: Re: [Haskell-beginners] containers and extensibility,
typeclasses vs. multiple value constructors
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"
Ok, I got basic implementations of both methods to work, and what's interesting
is how similar the syntax is. I'm going to post it here for anyone who wants
to comment, but also for anyone who stumbles upon this thread and wants to see
where it leads.
Here's the relevant parts of the Existential Types implementation:
{-# LANGUAGE ExistentialQuantification #-}
data RenderContext = RenderContext {}
class Plottable a where
renderPlot :: a -> RenderContext -> IO ()
data PlotWrap = forall a. Plottable a => PlotWrap a
instance Plottable PlotWrap where
renderPlot (PlotWrap a) = renderPlot a
data ScatterPlot = ScatterPlot {scatterPoints :: [(Double,Double)]
,pointColor :: Color
,pointSize :: GL.GLfloat}
defScatterPlot = ScatterPlot {scatterPoints=[]
,pointColor = red
,pointSize = 1}
instance Plottable ScatterPlot where
renderPlot plot@(ScatterPlot {}) context = do
GL.color $ pointColor plot
GL.pointSize $= pointSize plot
GL.renderPrimitive GL.Points $ mapM_ GL.vertex (map pair2vertex $
scatterPoints plot)
Which I use by creating ScatterPlots (the noise functions aren't worth showing
here, but they let me plot random data):
testScatter=defScatterPlot {scatterPoints=zip (map (*1) (take 2000 $
uniformNoise 0))
(map (*1) (take 2000 $
uniformNoise 1))}
testScatter2=defScatterPlot {scatterPoints=zip (map (\x -> 5 + x ) (take 2000 $
gaussianNoise 0))
(map (\x -> 5 + x ) (take 2000 $
gaussianNoise 1))}
and then calling this in the OpenGL display callback:
mapM_ (($ RenderContext) . renderPlot) [PlotWrap testScatter,PlotWrap
testScatter2]
-----------------------------------------------------------------------------------------------------
Now here's the "thunked" version (perhaps I'm abusing the term?):
data RenderContext = RenderContext {}
data PlotThunk = PlotThunk {renderer :: RenderContext -> IO ()}
class Plottable a where
renderPlot :: a -> RenderContext -> IO ()
createThunk :: a -> PlotThunk
createThunk x = PlotThunk {renderer = renderPlot x}
instance Plottable PlotThunk where
renderPlot p context=(renderer p) context
createThunk x = x
data ScatterPlot = ScatterPlot {scatterPoints :: [(Double,Double)]
,pointColor :: Color
,pointSize :: GL.GLfloat}
defScatterPlot = ScatterPlot {scatterPoints=[]
,pointColor = red
,pointSize = 1}
instance Plottable ScatterPlot where
renderPlot plot@(ScatterPlot {}) context = do
GL.color $ pointColor plot
GL.pointSize $= pointSize plot
GL.renderPrimitive GL.Points $ mapM_ GL.vertex (map pair2vertex $
scatterPoints plot)
I create the ScatterPlots in exactly the same way:
testScatter=defScatterPlot {scatterPoints=zip (map (*1) (take 2000 $
uniformNoise 0))
(map (*1) (take 2000 $
uniformNoise 1))}
testScatter2=defScatterPlot {scatterPoints=zip (map (\x -> 5 + x ) (take 2000 $
gaussianNoise 0))
(map (\x -> 5 + x ) (take 2000 $
gaussianNoise 1))}
and then use this to in the OpenGL callback:
mapM_ (($ RenderContext) . renderPlot) [createThunk testScatter,createThunk
testScatter2]
------------------------------------------------------------
The principle differences I see so far (more may appear as I add more plot
styles) are these:
Both versions require creating one additional data type and an added function
call when creating the list (creating the thunk, or wrapping the data). The
existential type version requires the use of a language extension, but has less
confusing syntax and looks like a value construction when forming that list.
The thunked version has a slightly more complex class definition, but the
calling code is no more complex than the existential typed version.
Cheers--
Greg
On Sep 6, 2010, at 11:44 PM, Greg Best wrote:
> Two great suggestions (attached below for context), thanks to Daniel and
> Stephen, both.
>
> Since a large part of my goal here is to learn the language, I'll probably
> try both of these just to make sure I can.
>
>> From a cultural standpoint, is there a preferred approach? Existential
>> Types sits more nicely with my OO background and is a more exact
>> interpretation of what I was trying to do, but is that seen as "impure"
>> under Haskell? More generally, what should I keep in mind when using
>> language extensions? Are Existential Types supported across
>> implementations? Are they a likely candidate for adoption into the language
>> proper? Are there performance implications (such as future parallelization)?
>
> Stephen's solution is obvious now that it's been presented. I'm not planning
> on using GnuPlot, I'm mucking around with the OpenGL bindings, but the point
> is, I think, the same: don't make a list of of objects, make a list of
> functions. In this case, they'd be more along the lines of
> ApplicationContext -> IO ().
>
> I suppose I could also create a type that contains the disembodied methods
> from the various plot styles:
>
> data PlotThunks = PlotThunks { render:: Context -> IO ()
> , hitTest:: Point ->
> Bool
> , extents:: Context ->
> Rect}
>
> then functions (perhaps a typeclass method) that build values of that type
> from each of the various plot styles.
>
> plotList :: [PlotThunks]
>
> renderAll :: Context -> [PlotThunks] -> IO ()
> renderAll context plots= mapM_ (($ context) . render) plots
>
>
> Thanks again--
> Greg
>
>
>
> On Sep 6, 2010, at 6:14 AM, Daniel Fischer wrote:
>
>> you can combine the approaches. As long as all you want to do with your
>> container is rendering the contents,
>>
>> {-# LANGUAGE ExistentialQuantification #-}
>>
>> class Plot a where
>> render :: a -> IO ()
>> describe :: a -> String
>>
>> data SomePlot = forall p. Plot p => SomePlot p
>>
>> instance Plot SomePlot where
>> render (SomePlot p) = render p
>> describe (SomePlot p) = describe p
>>
>> gives you a class, so you can define new plot types without modifying the
>> library, and a wrapper type, so you can stick plots of different types in
>> the same container after wrapping them.
>> Once they're wrapped, you can't use anything but the methods of the Plot
>> class on them, though, so if you want to do anything else with the
>> container's contents, that won't work (you can do something with an
>> additional Typeable constraint).
>>
>> http://www.haskell.org/haskellwiki/Existential_type for more.
>
> On Sep 6, 2010, at 7:57 AM, Stephen Tetley wrote:
>
>> Supposing you are working with GnuPlot - one option is to make Plot a
>> functional type that takes a list of some polymorphic input data and
>> generates a 'GnuPlot' - where GnuPlot is a type representing output in
>> the GnuPlot format.
>>
>> type Plot a = [a] -> GnuPlot
>>
>> Or if GnuPlot accepts drawing styles...
>>
>> type Plot a = [a] -> DrawingStyle -> GnuPlot
>>
>> Plots are just functions, so clearly you can define as many as you
>> like and they are all the same type.
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://www.haskell.org/pipermail/beginners/attachments/20100907/4dd71279/attachment.html
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 27, Issue 16
*****************************************