You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
a good place to start is an introductory book such as Real World Haskell (O’Reilly), Programming in Haskell (Cambridge University Press), Learn You a Haskell for Great Good! (No Starch Press), or Haskell: The Craft of Functional Programming (Addison-Wesley).
The notion of “threads of control” does not make sense in a purely functional program, because there are no effects to observe, and the evaluation order is irrelevant. So concurrency is a structuring technique for effectful code; in Haskell, that means code in the IO monad.
A deterministic programming model is one in which each program can give only one result, whereas a nondeterministic programming model admits programs that may have different results, depending on some aspect of the execution.
For parallel programming, we would like to use deterministic programming models if at all possible.
While it is possible to do parallel programming using concurrency, that is often a poor choice because concurrency sacrifices determinism. In Haskell, most parallel programming models are deterministic.
However, it is important to note that deterministic programming models are not sufficient to express all kinds of parallel algorithms; there are algorithms that depend on internal nondeterminism, particularly problems that involve searching a solution space.
Additionally, I recommend installing ThreadScope. ThreadScope is a tool for visualizing the execution of Haskell programs and is particularly useful for gaining insight into the behavior of Parallel and Concurrent Haskell code.
While reading this book, I recommend that you have the following Documentation in hand:
The GHC User’s Guide.
The Haskell Platform library documentation, which can be found on the main Haskell Platform site. Any types or functions that are used in this book that are not explicitly described can be found documented there.
Documentation for packages not in the Haskell Platform, which can be found on Hackage.
To search for documentation for a particular function or type, use Hoogle.
The main thing that the parallel Haskell programmer has to think about is partitioning: dividing up the problem into pieces that can be computed in parallel.
Haskell is a lazy language which means that expressions are not evaluated until they are required
To be able to use parallelism effectively, it helps to have an intuition for how lazy evaluation works
for the purposes of parallelism, we really do care about the difference between 1 + 2 and 3, because 1 + 2 is a computation that has not taken place yet, and we might be able to compute it in parallel with something else.
The :sprintcommand prints the value of an expression without causing it to be evaluated:
ghci> let x = 1 + 2 :: Int
ghci> :sprint x
x = _
ghci> x
3
ghci> :sprint x
x = 3
Defining an expression causes a thunk to be built representing that expression.
A thunk remains unevaluated until its value is required. Once evaluated, the thunk is replaced by its value.
map:: (a->b) [a] -> [b]
map f []->[]map f (x:xs) -> f x:map f xs
The map function builds a lazy data structure. This might be clearer if we rewrite the definition of map to make the thunks explicit:
map:: (a->b) [a] -> [b]
map f []=[]map f (x:xs) =let
x' = f x
xs' =map f xs
in
x':xs'
Note that length ignores the head of the list, recursing on the tail, xs. So when length is applied to a list, it will descend the structure of the list, evaluating the list cells but not the elements.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
a good place to start is an introductory book such as Real World Haskell (O’Reilly), Programming in Haskell (Cambridge University Press), Learn You a Haskell for Great Good! (No Starch Press), or Haskell: The Craft of Functional Programming (Addison-Wesley).
The notion of “threads of control” does not make sense in a purely functional program, because there are no effects to observe, and the evaluation order is irrelevant. So concurrency is a structuring technique for effectful code; in Haskell, that means code in the IO monad.
A deterministic programming model is one in which each program can give only one result, whereas a nondeterministic programming model admits programs that may have different results, depending on some aspect of the execution.
For parallel programming, we would like to use deterministic programming models if at all possible.
While it is possible to do parallel programming using concurrency, that is often a poor choice because concurrency sacrifices determinism. In Haskell, most parallel programming models are deterministic.
However, it is important to note that deterministic programming models are not sufficient to express all kinds of parallel algorithms; there are algorithms that depend on internal nondeterminism, particularly problems that involve searching a solution space.
Additionally, I recommend installing ThreadScope. ThreadScope is a tool for visualizing the execution of Haskell programs and is particularly useful for gaining insight into the behavior of Parallel and Concurrent Haskell code.
While reading this book, I recommend that you have the following Documentation in hand:
The GHC User’s Guide.
The Haskell Platform library documentation, which can be found on the main Haskell Platform site. Any types or functions that are used in this book that are not explicitly described can be found documented there.
Documentation for packages not in the Haskell Platform, which can be found on Hackage.
To search for documentation for a particular function or type, use Hoogle.
The main thing that the parallel Haskell programmer has to think about is partitioning: dividing up the problem into pieces that can be computed in parallel.
Haskell is a lazy language which means that expressions are not evaluated until they are required
To be able to use parallelism effectively, it helps to have an intuition for how lazy evaluation works
for the purposes of parallelism, we really do care about the difference between 1 + 2 and 3, because 1 + 2 is a computation that has not taken place yet, and we might be able to compute it in parallel with something else.
The
:sprintcommand
prints the value of an expression without causing it to be evaluated:Defining an expression causes a thunk to be built representing that expression.
A thunk remains unevaluated until its value is required. Once evaluated, the thunk is replaced by its value.
The map function builds a lazy data structure. This might be clearer if we rewrite the definition of map to make the thunks explicit:
Note that length ignores the head of the list, recursing on the tail, xs. So when length is applied to a list, it will descend the structure of the list, evaluating the list cells but not the elements.
We can cause it to be fully evaluated by applying a function that demands the values of the elements, such as sum:
Beta Was this translation helpful? Give feedback.
All reactions