<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Arrays – Haskell – Aelve Guide</title><id>https://guide.aelve.com/haskell/feed/category/bpid18sd</id><updated>2016-05-20T15:07:15Z</updated><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/feed/category/bpid18sd"/><entry><id>sp1cefwa</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">accelerate</title><updated>2016-05-20T15:07:15Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;a href=&#34;http://www.acceleratehs.org&#34; class=&#34;item-name&#34;&gt;accelerate&lt;/a&gt;

  
  (&lt;a href=&#34;https://hackage.haskell.org/package/accelerate&#34;&gt;Hackage&lt;/a&gt;)
&lt;/h1&gt;&lt;p&gt;&lt;code&gt;Data.Array.Accelerate&lt;/code&gt; defines an embedded array language for computations for high-performance computing in Haskell. Computations on multi-dimensional, regular arrays are expressed in the form of parameterised collective operations, such as maps, reductions, and permutations. These computations may then be online compiled and executed on a range of architectures.&lt;/p&gt;
&lt;p&gt;A short tutorial on how to implement the Mandelbrot set in Accelerate is available &lt;a href=&#34;http://www.acceleratehs.org/examples/mandelbrot.html&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;A simple example:&lt;/h2&gt;
&lt;p&gt;As a simple example, consider the computation of a dot product of two vectors of floating point numbers:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;dotp ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Acc&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Vector&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Float&lt;/span&gt;) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Acc&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Vector&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Float&lt;/span&gt;) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Acc&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Scalar&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Float&lt;/span&gt;)
dotp xs ys &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; fold (&lt;span class=&#34;fu&#34;&gt;+&lt;/span&gt;) &lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt; (zipWith (&lt;span class=&#34;fu&#34;&gt;*&lt;/span&gt;) xs ys)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Except for the type, this code is almost the same as the corresponding Haskell code on lists of floats. The types indicate that the computation may be online-compiled for performance - for example, using &lt;code&gt;Data.Array.Accelerate.LLVM.PTX&lt;/code&gt; it may be on-the-fly off-loaded to the GPU.&lt;/p&gt;
&lt;h2&gt;Larger example: LULESH&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/tmcdonell/lulesh-accelerate&#34;&gt;LULESH-accelerate&lt;/a&gt; is in implementation of the Livermore Unstructured Lagrangian Explicit Shock Hydrodynamics (LULESH) mini-app. &lt;a href=&#34;https://codesign.llnl.gov/lulesh.php&#34;&gt;LULESH&lt;/a&gt; represents a typical hydrodynamics code such as &lt;a href=&#34;https://wci.llnl.gov/simulation/computer-codes/ale3d&#34;&gt;ALE3D&lt;/a&gt;, but is simplified and hard-coded to solve the Sedov blast problem on an unstructured hexahedron mesh.&lt;/p&gt;
&lt;p&gt;The Accelerate implementation remains high-level while maintaining excellent performance compared to the reference C+OpenMP (&amp;gt; 2x faster) and CUDA (same performance) implementations.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://raw.githubusercontent.com/tmcdonell/lulesh-accelerate/master/images/sedov-3d-LLNL.png&#34; alt=&#34;LULESH mesh&#34; /&gt;&lt;/p&gt;
&lt;h2&gt;Pros&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Can generate code for both multicore CPUs as well as GPUs, from the same source program&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Includes an array fusion and optimisation framework (similar to vector)&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Generated code for tight numeric loops often much better than that generated by GHC&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Cons&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Requires external dependencies (LLVM, CUDA)&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Currently not well tested on Windows&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Implemented as an embedded language, it can be a bit trickier to get the hang of initially, compared to a native library such as vector or repa.&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Ecosystem&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/accelerate-llvm-native&#34;&gt;accelerate-llvm-native&lt;/a&gt;: Backend supporting parallel execution on multicore CPUs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/accelerate-llvm-ptx&#34;&gt;accelerate-llvm-ptx&lt;/a&gt;: Backend supporting parallel execution on CUDA-capable NVIDIA GPUs. Requires a GPU with compute capability 2.0 or greater. See this &lt;a href=&#34;http://en.wikipedia.org/wiki/CUDA#Supported_GPUs&#34;&gt;table of supported GPUs&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/accelerate-examples&#34;&gt;accelerate-examples&lt;/a&gt;: Computational kernels and applications showcasing the use of Accelerate as well as a regression test suite, supporting function and performance testing. Examples include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An implementation of the &lt;a href=&#34;https://en.wikipedia.org/wiki/Canny_edge_detector&#34;&gt;Canny edge detection&lt;/a&gt; algorithm&lt;/li&gt;
&lt;li&gt;An interactive &lt;a href=&#34;https://en.wikipedia.org/wiki/Mandelbrot_set&#34;&gt;Mandelbrot set&lt;/a&gt; generator&lt;/li&gt;
&lt;li&gt;A particle-based simulation of stable fluid flows&lt;/li&gt;
&lt;li&gt;An &lt;em&gt;n&lt;/em&gt;-body simulation of gravitational attraction between solid particles&lt;/li&gt;
&lt;li&gt;An implementation of the &lt;a href=&#34;https://en.wikipedia.org/wiki/PageRank&#34;&gt;PageRank&lt;/a&gt; algorithm&lt;/li&gt;
&lt;li&gt;A simple interactive ray tracer&lt;/li&gt;
&lt;li&gt;A cellular automata simulation&lt;/li&gt;
&lt;li&gt;A &amp;quot;password recovery&amp;quot; tool, for dictionary lookup of MD5 hashes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/accelerate-io&#34;&gt;accelerate-io&lt;/a&gt;: Fast conversions between Accelerate arrays and other array formats (including vector and repa).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/accelerate-fft&#34;&gt;accelerate-fft&lt;/a&gt;: Discrete Fourier transforms, with FFI bindings to optimised implementations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/accelerate-bignum&#34;&gt;accelerate-bignum&lt;/a&gt;: Fixed-width large integer arithmetic.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/accelerate-blas&#34;&gt;accelerate-blas&lt;/a&gt;: Linear systems, matrix decompositions, and other numerical computations for use in Accelerate. Most operations are implemented efficiently via FFI calls to BLAS and LAPACK&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/colour-accelerate&#34;&gt;colour-accelerate&lt;/a&gt;: Colour representations in Accelerate (RGB, sRGB, HSV,
and HSL).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/gloss-accelerate&#34;&gt;gloss-accelerate&lt;/a&gt;: Generate gloss pictures from Accelerate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/gloss-raster-accelerate&#34;&gt;gloss-raster-accelerate&lt;/a&gt;: Parallel rendering of raster images and animations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/lens-accelerate&#34;&gt;lens-accelerate&lt;/a&gt;: Lens operators for Accelerate types.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/linear-accelerate&#34;&gt;linear-accelerate&lt;/a&gt;: Linear vector spaces in Accelerate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/mwc-random-accelerate&#34;&gt;mwc-random-accelerate&lt;/a&gt;: Generate Accelerate arrays filled with high quality pseudorandom numbers.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Notes&lt;/h2&gt;&lt;h1&gt;&lt;span id=&#34;item-notes-sp1cefwa-links&#34;&gt;&lt;/span&gt;Links&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://chimera.labs.oreilly.com/books/1230000000929/ch06.html&#34;&gt;An introduction to Accelerate&lt;/a&gt; from &lt;a href=&#34;http://chimera.labs.oreilly.com/books/1230000000929&#34;&gt;Parallel and Concurrent Programming in Haskell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.acceleratehs.org/examples/mandelbrot.html&#34;&gt;Tutorial for generating a Mandelbrot fractal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://hackage.haskell.org/package/accelerate-examples&#34;&gt;accelerate-examples&lt;/a&gt; – a package with example programs&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-sp1cefwa-imports&#34;&gt;&lt;/span&gt;Imports&lt;/h1&gt;&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;co&#34;&gt;-- The core library&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Data.Array.Accelerate&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;A&lt;/span&gt;

&lt;span class=&#34;co&#34;&gt;-- To generate parallel CPU code&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Data.Array.Accelerate.LLVM.CPU&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;CPU&lt;/span&gt;

&lt;span class=&#34;co&#34;&gt;-- To generate parallel code for CUDA GPUs&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Data.Array.Accelerate.LLVM.PTX&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;PTX&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/arrays-bpid18sd#item-sp1cefwa"/></entry><entry><id>z97p6xla</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">repa</title><updated>2016-04-14T10:01:13Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;a href=&#34;http://repa.ouroborus.net/&#34; class=&#34;item-name&#34;&gt;repa&lt;/a&gt;

  
  (&lt;a href=&#34;https://hackage.haskell.org/package/repa&#34;&gt;Hackage&lt;/a&gt;)
&lt;/h1&gt;&lt;p&gt;Fast, auto-parallelizable, multidimensional, kinda-complicated arrays. Well-suited for processing images and other matrix-like things.&lt;/p&gt;
&lt;h2&gt;Pros&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Like &lt;a href=&#34;https://hackage.haskell.org/package/vector&#34;&gt;vector&lt;/a&gt;, does fusion – when you apply several operations to an array, it doesn&#39;t necessarily create intermediate arrays.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Auto-parallelizable – pass &lt;code&gt;+RTS -N&lt;/code&gt; to your program and it&#39;ll probably become faster. (You can control the way parallelization happens.)&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Supports advanced operations with multidimensional arrays (slicing, reshaping, transposition, etc).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Overall performance is almost C-like.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Elements in the array are saved in a flat structure, even when the array is multidimensional&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Cons&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Harder to use than other libraries. Uses lots of type synonyms, polymorphism, and generally looks complicated.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Beside looking complicated, it easily can cause segmentation faults at runtime&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Ecosystem&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Algorithms:
&lt;a href=&#34;https://hackage.haskell.org/package/repa-algorithms&#34;&gt;repa-algorithms&lt;/a&gt; (DFT, FFT, randomness, and some other algorithms),
&lt;a href=&#34;https://hackage.haskell.org/package/repa-linear-algebra&#34;&gt;repa-linear-algebra&lt;/a&gt;,
&lt;a href=&#34;https://hackage.haskell.org/package/hmatrix-repa&#34;&gt;hmatrix-repa&lt;/a&gt;,
&lt;a href=&#34;https://hackage.haskell.org/package/repa-fftw&#34;&gt;repa-fftw&lt;/a&gt; (bindings for &lt;a href=&#34;http://www.fftw.org/&#34;&gt;fftw&lt;/a&gt; to do FFT/DFT)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Working with files:
&lt;a href=&#34;https://hackage.haskell.org/package/repa-io&#34;&gt;repa-io&lt;/a&gt; (read/write arrays as text, binary, or BMP),
&lt;a href=&#34;https://hackage.haskell.org/package/repa-devil&#34;&gt;repa-devil&lt;/a&gt; (process images with repa),
&lt;a href=&#34;https://hackage.haskell.org/package/repa-sndfile&#34;&gt;repa-sndfile&lt;/a&gt; (read/write sound files),
&lt;a href=&#34;https://hackage.haskell.org/package/JuicyPixels-repa&#34;&gt;JuicyPixels-repa&lt;/a&gt; (images)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Notes&lt;/h2&gt;&lt;h1&gt;&lt;span id=&#34;item-notes-z97p6xla-links&#34;&gt;&lt;/span&gt;Links&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://chimera.labs.oreilly.com/books/1230000000929/ch05.html&#34;&gt;an introduction to Repa&lt;/a&gt; from &lt;a href=&#34;http://chimera.labs.oreilly.com/books/1230000000929&#34;&gt;Parallel and Concurrent Programming in Haskell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://hackage.haskell.org/package/repa-examples&#34;&gt;repa-examples&lt;/a&gt; – a package with examples&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-z97p6xla-imports&#34;&gt;&lt;/span&gt;Imports&lt;/h1&gt;&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;import qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Array.Repa&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;R&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/arrays-bpid18sd#item-z97p6xla"/></entry><entry><id>zf02sw64</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">bytestring</title><updated>2016-04-14T10:01:03Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;bytestring&lt;/span&gt;

  
  (&lt;a href=&#34;https://hackage.haskell.org/package/bytestring&#34;&gt;Hackage&lt;/a&gt;)
&lt;/h1&gt;&lt;p&gt;Arrays of bytes. (You could use &lt;code&gt;Vector Word8&lt;/code&gt; instead, but most applications don&#39;t.)&lt;/p&gt;
&lt;p&gt;Useful whenever you need, well, arrays of bytes. Can be faster than &lt;code&gt;Vector&lt;/code&gt; (at least &lt;a href=&#34;https://mail.haskell.org/pipermail/haskell/2011-October/023021.html&#34;&gt;it was true in 2011&lt;/a&gt;).&lt;/p&gt;
&lt;h2&gt;Pros&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Widely used.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Can be faster than &lt;code&gt;Vector&lt;/code&gt;s.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Can be infinite (as lazy bytestrings).&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Cons&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;There&#39;s no mutable interface for bytestrings (apart from convering them to &lt;code&gt;CString&lt;/code&gt;s and then using pointers).&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Ecosystem&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Parsing: most parsing libraries can parse bytestrings, but &lt;a href=&#34;https://hackage.haskell.org/package/attoparsec&#34;&gt;attoparsec&lt;/a&gt; is most commonly used, and &lt;a href=&#34;https://hackage.haskell.org/package/attoparsec/docs/Data-Attoparsec-Zepto.html&#34;&gt;&lt;code&gt;Data.Attoparsec.Zepto&lt;/code&gt;&lt;/a&gt; is even faster for some kinds of parsing. There are also &lt;a href=&#34;https://hackage.haskell.org/package/binary-parser&#34;&gt;binary-parser&lt;/a&gt; and &lt;a href=&#34;https://hackage.haskell.org/package/scanner&#34;&gt;scanner&lt;/a&gt; (which I haven&#39;t tried)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fast builders: &lt;a href=&#34;https://hackage.haskell.org/package/bytestring-tree-builder&#34;&gt;bytestring-tree-builder&lt;/a&gt;, &lt;a href=&#34;https://hackage.haskell.org/package/fast-builder&#34;&gt;fast-builder&lt;/a&gt;, &lt;a href=&#34;https://hackage.haskell.org/package/buffer-builder&#34;&gt;buffer-builder&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Serialisation: &lt;a href=&#34;https://hackage.haskell.org/package/binary&#34;&gt;binary&lt;/a&gt;, &lt;a href=&#34;https://hackage.haskell.org/package/cereal&#34;&gt;cereal&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Encoding: &lt;a href=&#34;https://hackage.haskell.org/package/base64-bytestring&#34;&gt;base64-bytestring&lt;/a&gt;, &lt;a href=&#34;https://hackage.haskell.org/package/base32-bytestring&#34;&gt;base32-bytestring&lt;/a&gt;, &lt;a href=&#34;https://hackage.haskell.org/package/base16-bytestring&#34;&gt;base16-bytestring&lt;/a&gt; (hex encoding)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replacements for &lt;code&gt;Read&lt;/code&gt;/&lt;code&gt;Show&lt;/code&gt;: &lt;a href=&#34;https://hackage.haskell.org/package/bytestring-show&#34;&gt;bytestring-show&lt;/a&gt;, &lt;a href=&#34;https://hackage.haskell.org/package/readable&#34;&gt;readable&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Streaming: &lt;a href=&#34;https://hackage.haskell.org/package/pipes-bytestring&#34;&gt;pipes-bytestring&lt;/a&gt;, &lt;a href=&#34;https://hackage.haskell.org/package/quiver-bytestring&#34;&gt;quiver-bytestring&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Data structures: &lt;a href=&#34;https://hackage.haskell.org/package/rope&#34;&gt;rope&lt;/a&gt; (for manipulating very long strings efficiently, i.e. the &lt;a href=&#34;https://en.wikipedia.org/wiki/Rope_(data_structure)&#34;&gt;rope data structure&lt;/a&gt;), &lt;a href=&#34;https://hackage.haskell.org/package/bytestring-trie&#34;&gt;bytestring-trie&lt;/a&gt; (trees of bytestrings with common prefixes, i.e. the &lt;a href=&#34;https://en.wikipedia.org/wiki/Trie&#34;&gt;trie data structure&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Various: &lt;a href=&#34;https://hackage.haskell.org/package/bytestring-delta&#34;&gt;bytestring-delta&lt;/a&gt; (diffing bytestrings / producing patches and applying them to bytestrings), &lt;a href=&#34;https://hackage.haskell.org/package/bytestring-mmap&#34;&gt;bytestring-mmap&lt;/a&gt; (accessing files/devices as bytestrings, see &lt;a href=&#34;https://en.wikipedia.org/wiki/Mmap&#34;&gt;mmap&lt;/a&gt;), &lt;a href=&#34;https://hackage.haskell.org/package/stringsearch&#34;&gt;stringsearch&lt;/a&gt; (splitting/search/replacement), &lt;a href=&#34;https://hackage.haskell.org/package/bytestring-plain&#34;&gt;bytestring-plain&lt;/a&gt; (compact representation for short bytestrings, claimed to be better than &lt;code&gt;Data.ByteString.Short&lt;/code&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/arrays-bpid18sd#item-zf02sw64"/></entry><entry><id>ajh4pkjz</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">array</title><updated>2016-04-14T10:00:57Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;array&lt;/span&gt;

  
  (&lt;a href=&#34;https://hackage.haskell.org/package/array&#34;&gt;Hackage&lt;/a&gt;)
&lt;/h1&gt;&lt;p&gt;This library is &lt;a href=&#34;https://www.haskell.org/onlinereport/haskell2010/haskellch14.html#x22-20100014&#34;&gt;in the Haskell report&lt;/a&gt;, but it&#39;s used less often than &lt;a href=&#34;https://hackage.haskell.org/package/vector&#34;&gt;vector&lt;/a&gt;. You might want to use it if you&#39;re on a new machine and don&#39;t have vector installed yet, or if you want multidimensional arrays (or arrays with indexing that doesn&#39;t start from 0).&lt;/p&gt;
&lt;h2&gt;Pros&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Bundled with GHC.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Supports multidimensional arrays.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Keys do not have to be integers.&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Cons&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;The API is pretty minimal.&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Notes&lt;/h2&gt;&lt;h1&gt;&lt;span id=&#34;item-notes-ajh4pkjz-types-and-modules&#34;&gt;&lt;/span&gt;Types and modules&lt;/h1&gt;&lt;p&gt;First of all, an array index can be of any type belonging to the &lt;code&gt;Ix&lt;/code&gt; typeclass – this includes &lt;code&gt;Int&lt;/code&gt;, &lt;code&gt;Integer&lt;/code&gt;, &lt;code&gt;Bool&lt;/code&gt;, &lt;code&gt;Char&lt;/code&gt;, and tuples (which enables multidimensional arrays).&lt;/p&gt;
&lt;p&gt;There are immutable and mutable arrays. Immutable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Array i e&lt;/code&gt; – arrays (with index type &lt;code&gt;i&lt;/code&gt; and element type &lt;code&gt;e&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UArray&lt;/code&gt; – unboxed arrays (faster and take less space, but all elements have to be evaluated)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mutable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IOArray&lt;/code&gt; – arrays in the &lt;code&gt;IO&lt;/code&gt; monad&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IOUArray&lt;/code&gt; – unboxed arrays in the &lt;code&gt;IO&lt;/code&gt; monad&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STArray&lt;/code&gt; – arrays in the &lt;code&gt;ST&lt;/code&gt; monad&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STUArray&lt;/code&gt; – unboxed arrays in the &lt;code&gt;ST&lt;/code&gt; monad&lt;/li&gt;
&lt;li&gt;&lt;code&gt;StorableArray&lt;/code&gt; – arrays that are compatible with C&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They live in their corresponding modules (&lt;code&gt;Data.Array&lt;/code&gt;, &lt;code&gt;Data.Array.Unboxed&lt;/code&gt;, &lt;code&gt;Data.Array.IO&lt;/code&gt;, &lt;code&gt;Data.Array.ST&lt;/code&gt;, &lt;code&gt;Data.Array.Storable&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;There are also modules that provide generic interfaces for arrays – &lt;code&gt;Data.Array.MArray&lt;/code&gt; for mutable arrays and &lt;code&gt;Data.Array.IArray&lt;/code&gt; for immutable arrays. They&#39;re reexported by other modules so you don&#39;t have to import them implicitly, with one exception: &lt;code&gt;Data.Array&lt;/code&gt; doesn&#39;t reexport &lt;code&gt;Data.Array.IArray&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-ajh4pkjz-unsafe-operations&#34;&gt;&lt;/span&gt;Unsafe operations&lt;/h1&gt;&lt;p&gt;&lt;code&gt;Data.Array.Base&lt;/code&gt; provides some unsafe operations that don&#39;t perform any checks (and therefore are faster). The documentation for it is unavailable, but you can &lt;a href=&#34;https://hackage.haskell.org/package/array/docs/src/Data.Array.Base.html&#34;&gt;look at the source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here are the unsafe operations for immutable arrays (&lt;code&gt;a&lt;/code&gt; is the type of the array):&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;co&#34;&gt;-- Unsafe version of (!)&lt;/span&gt;
&lt;span class=&#34;ot&#34;&gt;unsafeAt         ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Ix&lt;/span&gt; i &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; a i e &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; e
&lt;span class=&#34;co&#34;&gt;-- Unsafe version of (//)&lt;/span&gt;
&lt;span class=&#34;ot&#34;&gt;unsafeReplace    ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Ix&lt;/span&gt; i &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; a i e &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; [(&lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;, e)] &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; a i e

&lt;span class=&#34;ot&#34;&gt;unsafeArray      ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Ix&lt;/span&gt; i &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; (i,i) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; [(&lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;, e)] &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; a i e
&lt;span class=&#34;ot&#34;&gt;unsafeAccum      ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Ix&lt;/span&gt; i &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; (e &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; e&#39; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; e) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; a i e &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; [(&lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;, e&#39;)] &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; a i e
&lt;span class=&#34;ot&#34;&gt;unsafeAccumArray ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Ix&lt;/span&gt; i &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; (e &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; e&#39; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; e) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; e &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; (i,i) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; [(&lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;, e&#39;)] &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; a i e&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here are the ones for mutable arrays:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;unsafeRead      ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Ix&lt;/span&gt; i &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; a i e &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; m e
&lt;span class=&#34;ot&#34;&gt;unsafeWrite     ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Ix&lt;/span&gt; i &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; a i e &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; e &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; m ()

&lt;span class=&#34;ot&#34;&gt;unsafeNewArray_ ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Ix&lt;/span&gt; i &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; (i,i) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; m (a i e)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Beware: all of these use zero-based indexing. If your array starts with 1, for instance, you still have to use 0 as the index to access the 1st element.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/arrays-bpid18sd#item-ajh4pkjz"/></entry><entry><id>qp2q4mys</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">vector</title><updated>2016-04-14T10:00:54Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;vector&lt;/span&gt;

  
  (&lt;a href=&#34;https://hackage.haskell.org/package/vector&#34;&gt;Hackage&lt;/a&gt;)
&lt;/h1&gt;&lt;p&gt;The de facto standard array type used in Haskell. Fast. Used by many libraries.&lt;/p&gt;
&lt;p&gt;Note that it&#39;s not quite like C++ &lt;code&gt;vector&lt;/code&gt;. (For instance, it doesn&#39;t support fast append.)&lt;/p&gt;
&lt;p&gt;A tutorial can be found at &lt;a href=&#34;https://haskell-lang.org/library/vector&#34;&gt;https://haskell-lang.org/library/vector&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Pros&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Supports list-like operations and has an extensive API.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Well-optimised; supports stream fusion (when you create an array and then consume it, sometimes it won&#39;t actually have to allocate any memory for the array).&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Cons&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Doesn&#39;t support multidimensional arrays.&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Ecosystem&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/vector-algorithms&#34;&gt;vector-algorithms&lt;/a&gt; (sorting, binary search), &lt;a href=&#34;https://hackage.haskell.org/package/vector-random&#34;&gt;vector-random&lt;/a&gt; (generate vectors with random values), &lt;a href=&#34;https://hackage.haskell.org/package/hybrid-vectors&#34;&gt;hybrid-vectors&lt;/a&gt; (mix boxed and unboxed elements), &lt;a href=&#34;https://hackage.haskell.org/package/patches-vector&#34;&gt;patches-vector&lt;/a&gt; (diff 2 vectors)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/vector-th-unbox&#34;&gt;vector-th-unbox&lt;/a&gt; (a helper for defining unboxed vector instances)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/vector-instances&#34;&gt;vector-instances&lt;/a&gt; (orphan instances),
&lt;a href=&#34;https://hackage.haskell.org/package/cereal-vector&#34;&gt;cereal-vector&lt;/a&gt;,
&lt;a href=&#34;https://hackage.haskell.org/package/vector-binary-instances&#34;&gt;vector-binary-instances&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/pipes-vector&#34;&gt;pipes-vector&lt;/a&gt;, &lt;a href=&#34;https://hackage.haskell.org/package/vector-conduit&#34;&gt;vector-conduit&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Notes&lt;/h2&gt;&lt;h1&gt;&lt;span id=&#34;item-notes-qp2q4mys-links&#34;&gt;&lt;/span&gt;Links&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/commercialhaskell/haskelldocumentation/blob/master/content/vector.md&#34;&gt;a tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-qp2q4mys-imports&#34;&gt;&lt;/span&gt;Imports&lt;/h1&gt;&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;co&#34;&gt;-- ordinary vectors&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;import qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Vector&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;V&lt;/span&gt;

&lt;span class=&#34;co&#34;&gt;-- mutable vectors&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;import qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Vector.Mutable&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;VM&lt;/span&gt;

&lt;span class=&#34;co&#34;&gt;-- unboxed vectors&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;import qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Vector.Unboxed&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;U&lt;/span&gt;

&lt;span class=&#34;co&#34;&gt;-- mutable unboxed vectors&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;import qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Vector.Unboxed.Mutable&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;UM&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-qp2q4mys-gotchas&#34;&gt;&lt;/span&gt;Gotchas&lt;/h1&gt;&lt;p&gt;Unlike in C++, growing a vector by one element isn&#39;t a constant-time operation (in C++ it is most of the time).&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/arrays-bpid18sd#item-qp2q4mys"/></entry></feed>