Practical Concurrent Haskell with Big Data Applications pdf pdf
CHAPTER 1 Introduction The general goal of this book, Practical Concurrent Haskell: With Big Data Applications, is to give
Concurrent and distributed programming in Haskell could be a challenging task, but once it has been accomplished and well integrated with a cloud environment, you will have a strong, reliable, efficient,secure, and portable platform for software applications. Programming for the cloud with Haskell requires a generic network transportation API, importing and using libraries for sending static closure to remote nodes, and the power of API for distributed programming.
What Is Haskell?
The shallow similarities between thedescription of evaluation strategies has led programming language researchers to speculate that the two strategies are identical—a belief that can be observed in popular books from the early 1980s; but as we To illustrate how the evaluation strategy is working, we have two examples: one in C++ and one in Haskell. Haskell is a functional language because the evaluation process of a program is equal to the evaluation of a function in the purest and natural mathematical way.
The Cloud and Haskell
The API,such as the efforts to combine Erlang-style concurrent and distributed programming in Haskell to provide generic network transport API, libraries intended to send static closures to remote nodes, or a very rich APIfor distributed programming API, are and represents couple of examples of what we can use in the process of developing applications in Haskell for cloud environments. Designing the modules (figure from http://haskell-distributed.github.io/wiki/ newdesign.html ) According to the official documentation ( http://haskell-distributed.github.io/wiki/newdesign.html ), applications designed and developed with Haskell are encouraged to use the Cloud Haskell Layer.
Functional vs. Object-Oriented Programming
Broadly, the similarities between the two programming paradigms are in the levels of expressive power and the capabilities of encapsulating programs into more compact pieces that could be (re)combined. The most important principle of OOP is that the data and the operations applied on that data are closely linked: an object contains its own data and the specific implementation of the operations on the owned data.
The command for :reload, followed by the name of the file.recompilation is Functions You have used functions since the beginning of this section; for example, all arithmetic operators are functions with two parameters or the functions applied to lists. When a piece of code changes the value of the variable, it affects the function in a particularway, which has a secondary effect; although our function does not change the value of the global variable, which is treated as a constant.
When -fprint-bind-result is enabled, the outcome of a statement is typed if the statement does not represent a binding, or it is a binding to a single variable The binding could also be done using the let statement. ( 4^): the left side is the same to (^) 4, or more formal \a -> 4 ^ a Sectioning a function is very useful because it allows you to write a function, without giving a particular name to that function; for example:( 1+): the function which increments by one a value Local Declarations In Haskell, local declarations can be used.
Rules for Instance Termination -XUndecidableInstances defines instances that could result in type-checker non-termination
■ If you want a list of the first 50 integers, you would not write all of them; you would do like this:Prelude> [1..50] This approach is called ranges, which enumerates the elements of a list (it has an enumeration rule!) in a compact manner. Prelude> data Figure = Triangle Float Float Float | Square Float data Figure = Triangle Float Float Float | Square FloatPrelude> :t TriangleTriangle :: Float -> Float -> Float -> FigurePrelude> :t SquareSquare :: Float -> Figure Next, let’s compute the perimeters of the two figures.perimeter :: Figure -> Float perimeter (Triangle a b c) = a + b + cperimeter (Square a) = 4 * a Let’s observe that the type of the perimeter is Figure.
Parallelism for Dataflow
To make it less demandingto characterize parMap, let’s first form a basic deliberation for a parallel calculation that profits an outcome.spawn :: NFData object_A => Par object_A -> Par (IVar object_A) spawn varP = dovarI <- new fork (do varX <- varP; put varI varX)return varI The preceding is an example in which the spawn function forks the computation in parallel and returns an object of type IVar that can be used in to wait for the result. A parallel map is formed on calling spawn to invoke and apply the function for all the elements of the queue, and then waiting for the response with all the results.parMapM :: NFData object_B => (object_A -> Par object_B) -> [object_A] -> Par [object_B] parMapM varF as = dovarIBS <- mapM (spawn.varF) as mapM get varIBS ( parMapM is also provided by Control.
The mainLoop function builds a socket-server example equivalent to the classical “Hello World!” When there is a certain socket, do the following: accept the connection, receive and pass an easy “Hello World!”,close the open connection, and reutilize the genuine socket. If it is limited to only read the flow of the messages, then that is sufficient; but in practice, it is more complicated because the server shouldmanipulate the chat.
The Final Code
For example, the expression 4-7 is stated in the (:) of the list, and it is not in the normal formWHNF form because its root is an instance of the constructor because the first parameter has a redex. The following is a standard example of divide and conquer from originalarticle Architecture aware parallel programming in Glasgow Parallel Haskell by Mustafa Kh Aswad, where the strategies are used to separate algorithms from parallelism.divConq :: (a -> b) The DivConq function splits the main problem (which is not trivial) into subproblems of the same type, and then it applies the f schema to every subproblem.
Maybe Let’s start with a simple example. We have a list of integers and we want to divide each by a number
But we want Nothing to be returned only for the 0 values, and the result of the division to be returned for the rest of the elements. Forexample, tail has the following versions.tail :: [a] -> [a]: The error occur on tail  The use of Either is similar to the use of Maybe, but there is an important difference: Either can bind connected information for both a failure and a success.
Lazy Evaluation and Exceptions Let’s run the following program
For that, we use the handle function, which has twosides: the second side is the function we want to call, and the first side is called in case of failure. If the program throws an exception, but it is not caught by any function, it will display a common error message; but when it comes to dynamic exceptions, which are unknown to the system, the message will notbe clear.
CHAPTER 6 Cancellation When working with interactive applications, a thread may need to break another thread execution in a particular situation. The following are some general examples
The way that asynchronous bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO cThis function allows the programmer setting up exception handling to deallocate some resources or tobracket a b c, then a represents the operation that assigns the resource,apply tidy-up operations. The bracket.following is the definition ofbracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c bracket ahead after current = doa <- ahead c <- current a `onException` after aafter a return c IO monad, and the best practice in writingYou already know that exceptions are a useful part of the IO monad is to make use of bracket, and then to gain and issue resources in a proper way.code with thebracket should continue its job even if a thread is aborted.
Using Asynchronous Exceptions with mask
It is a little difficult, but the following is an example that shows how the combinatoroperates.situation :: MVar a -> (a -> IO a) -> IO () situation mVar f = mask $ \restore -> doa <- takeMVar mVar rVar <- restore (f a) `catch` \e -> do putMVar mVar a; throw eputMVar mVar rVar The argument of mask is a function, which has the restore function as a parameter that brings an asynchronous exception to its actual state while the argument of mask is executing. The following modified the values of the two MVars in a safe way.modifyTwoValues :: MVar a -> MVar b -> (a -> b -> IO (a,b)) -> IO () modifyTwoValues maValue mbValue f =modifyMVar_ mbValue $ \b -> modifyMVar maValue $ \a -> f a b When it is blocked inside modifyMVar, and an exception occurs, the content of MVar is restored to the initial value, with the help of an outside modifyMVar_.
Writing Safe Channels Using Asynchronous Exceptions
Do not forget that readMVar has the following definition.readMVar :: MVar a -> IO a putMVar m a return aLooking at the readMVar definition, notice that when an exception occurs after the execution oftakeMVar, but before the execution of readMVar, the content of the MVar is empty; therefore, it is necessaryto assure the safety here, also. $ ./catch-mask xxx yyyUnmaskedMaskedInterruptible In the first iteration of the loop function, the state is Unmasked, which is good; but in the next iteration, it is reported that the current state is MaskedInterruptible, which is bad, because the synchronous exceptionshould not be masked starting at the secondary iteration.
Introducing Transactional Memory
The STM transactions are found in the STM monad.data STM a instance Monad STM Transactions are executed using a special function called atomically, which is covered in a later in this chapter.atomically :: STM a -> IO a A very important and useful primitive is represented by retry, a function that cancels the actual transaction and reloads it in case any dependencies are modified during transactions in different threads. The mostimportant operations done in an STM action are reading and writing transactional variables, which have TVar a type; like IORefs, it could be read or written in an IO action.readTVar :: TVar a -> STM a writeTVar :: TVar a -> a -> STM () Like IO actions, the STM actions can be formed with the same do notation, because it has an implementation for every type.
Transactional Memory Version
Of course, at the same time, there could be more threads that read and When the act is performed, the log is verified, and if the result is success, then the log is committed. We have globalized all that we have explained in the followingcheck function.checkAcc :: Bool -> STM () The following is another version of limitedWithdrawAmount.limitedWithdrawAmount :: Account -> Int -> STM () limitedWithdrawAmount account moneyAmount = dobal <- readTVar account checkAcc (moneyAmount <= 0 || moneyAmount <= bal)writeTVar account (bal - moneyAmount) Here is the code in which we added the check function.import System.
CHAPTER 8 Debugging Techniques Used in Big Data In this chapter, you learn what big data means and how Haskell can be integrated with big data. You also see some debugging techniques. Data Science There is critical and developing interest in data science by the data-savvy experts at organizations, open
In a recent review by the McKinsey Global Institute, an expert remarked: “A shortage of the analytical and managerial talent necessary to make the most of big data is a significant and pressing challenge (for theUnited States).” The report states that by 2018 there will be 4 to 5 million jobs in the United States that require data analysis aptitude. There willbe a need for 1.5 million managers and examiners with investigative and specialized abilities “who can ask the right questions and consume the results of analysis of big data effectively.” Information becomes inexpensive and omnipresent.
The focus of data mining is to obtain predictions, which helps with decision making. It is strong, simple to use, and has • an open source group behind it.
Haskell for Big Data
The following are some of the tools that Haskell provides for working with large data set.hspark Cloud Haskell hspark A new library inspired by Apache Spark, it is useful in distributed, in-memory computations. A configuration of a cluster is taken as input and the jobs are translated into a set of distributed jobs, making use of the distributed-process Cloud Haskell library.
The purpose of the Hadron library is to use type- safety in the complex and sensitive world of HadoopStreaming MapReduce. The following is an example of ZeroMQ usage in displaying the input for a socket ( https://gitlab.com/twittner/zeromq-haskell ).
The Developer’s Perspective
Every programminglanguage only needs to implement an interface that does not rely on features specific to Java virtual machines, and that can be implemented using standard REST technologies. The User’s Perspective Citing Readme file from github page of Krapsh library, the following are some features of the Krapsh library.
Haskell vs. Data Science
We will generate a key based on the current time, subtracting theseconds component of time from the large value to reverse the order of the generated keys.newId :: IO String newId = do(TOD seconds picos) <- getClockTime return $ show (9999999999 - seconds) ++ show picos With the preceding piece of code, now we can implement the method through which a new note is added. When a process expects a certain type of message (in this case, it is “selected” via the type annotation"Process String"; in other cases, the type of message might be inferred) and it is not in the mailbox, the process is blocked until it receives the expected message.
Traditionally, static actions are difficult to create, but Cloud Haskell improves this issue with TemplateHaskell, as such as when we have a monomorphic function f::T1 -> T2 then $(mkClosure 'f) :: T1 -> Closure T2, provided that T2 is serializable.mkClosure is a useful function that can make every top-level unary function in a Closure. The signal and the components are analyzed for decidingthe action that needs to be taken by the receiver as a response for the termination of the monitored process.
Receiving and Matching
In cloud Haskell is it guaranteed that the messages are sent in First in First out (FIFO) order between two concurrent processes, but this is not always true between an arbitrary numbers of processes. When it uses expect for a message, then we actually ignore the order of messages because we need a message with content that is decoded into a certain type.