Haskell: parallel do versus list comprehension - haskell

To make a list comprehension run in parallel, it's easy to tack on using parList rdeepseq, but what if the list comprehension is expressed using do notation?
For example, this bit of code runs just fine in parallel.
entry n = [ (rowSet,finalEV rowSet,rrDone rowSet,oneRRLeft rowSet,twoRRLeft rowSet) | rowSet <- getChoiceList 13 n] `using` parList rdeepseq
where
prevFinal = getFinalEVNEW $ entry (n-1)
rrDone rowSet = (getRRDoneNEW prevFinal rowSet)
doneStripped rowSet = map (\(v,_,ev) -> (v,ev)) (rrDone rowSet)
oneRRLeft rowSet = getRRChoicesNEW (doneStripped rowSet)
oneRRStripped rowSet = map (\(v,_,ev) -> (v,ev)) (oneRRLeft rowSet)
twoRRLeft rowSet = getRRChoicesNEW (oneRRStripped rowSet)
twoRRStripped rowSet = map (\(v,_,ev) -> (v,ev)) (twoRRLeft rowSet)
finalEV rowSet = weightedEV theProbs (twoRRStripped rowSet)
But it's easier to read when expressed with do notation. The part above, expressed in do form, and with the broader context becomes:
monster :: [[([Bool],Double,[([Int],Int,Double)],[([Int],[Bool],Double)],[([Int],[Bool],Double)])]]
monster = [ entry i | i <- [0..13] ]
where
entry 0 = [(replicate 13 False,0,[],[],[])]
entry n = go ( getFinalEVNEW ( entry (n-1) ) )
where
go prevFinal = do
rowSet <- (getChoiceList 13 n )
let rrDone = (getRRDoneNEW prevFinal rowSet)
let doneStripped = map (\(v,_,ev) -> (v,ev)) rrDone
let oneRRLeft = getRRChoicesNEW doneStripped
let oneRRStripped = map (\(v,_,ev) -> (v,ev)) oneRRLeft
let twoRRLeft = getRRChoicesNEW oneRRStripped
let twoRRStripped = map (\(v,_,ev) -> (v,ev)) twoRRLeft
let finalEV = weightedEV theProbs twoRRStripped
return (rowSet,finalEV,rrDone,oneRRLeft,twoRRLeft)
But it's unclear how to make the do form run in parallel.
Is there a straightforward way to transform a parallel list comprehension to an equivalent do form?
EDIT: The "do version" was expanded a bit for context.
A related issue is the fact the algorithm is recursive, and any attempt to parallelize entry n should wait until entry (n-1) is in normal form. Right?
This is a calculation for a solution to a game similar to Yahtzee. It's a "let's learn Haskell" exercise.

The straightforward translation of the code you say works looks like this:
entry n = go ( getFinalEVNew ( entry (n-1) ) ) `using` parList rdeepseq
If you insist on attaching the using clause to the do block, you can either use parentheses:
go prevFinal = (do
...
) `using` parList rdeepseq
or use an indentation level between that of the where block and the do block:
go prevFinal = do
...
`using` parList rdeepseq
or apply using in prefix:
go prevFinal = (`using` parList rdeepseq) $ do
...

Related

OCaml equivalent to Haskell's # in pattern matching (a.k.a. as-pattern)

In Haskell, while pattern matching, I can use # to get the entire structure in a pattern. (For easier Googling, this structure is known as an as-pattern.)
For example, x:xs decomposes a list into a head and a tail; I can also get the entire list with xxs#(x:xs).
Does OCaml have something like this?
You can use as:
let f = function
| [] -> (* ... *)
| (x::xs) as l ->
(*
here:
- x is the head
- xs is the tail
- l is the whole list
*)
Let me extend Etienne's answer a little bit with some examples:
let x :: xs as list = [1;2;3];;
val x : int = 1
val xs : int list = [2; 3]
val list : int list = [1; 2; 3]
When you write <pattern> as <name>, the variable <name> is bound to the whole pattern on the left, in other words, the scope of as extends as far to the left as possible (speaking more techically as has lower priority than constructors, i.e., the constructors bind tighter). So, in case of the deep pattern matching, you might need to use parentheses to limit the scope, e.g.,
let [x;y] as fst :: ([z] as snd) :: xs as list = [[1;2];[3]; [4]];;
val x : int = 1
val y : int = 2
val fst : int list = [1; 2]
val z : int = 3
val snd : int list = [3]
val xs : int list list = [[4]]
val list : int list list = [[1; 2]; [3]; [4]]

variable not in scope - list comprehesion

I'm trying construct a function that return a list with the sum of tuples elements when is higher than 100.
resultSum :: [(Integer)] -> [Integer]
resultSum (x:xs) = [ sumT | let sumT = fst x + snd x in sumT + trd x, sumT > 100 ]
trd (_,_,x) = x
I'm receiving the message:
Not in scope: `sumT'
I figured that when I use the let I'm specifying who is my variable
PS: I need to user letand list comprehesion
I assume you want to get all 3-tuples in a list of 3-tuples where the sum of the components is greater than 100 and you want somehow to use let inside the listcomprehension.
First of all: the type of your expression is not correct, it should probably be:
resultSum :: [(Integer,Integer,Integer)] -> [Integer]
Try the following solution:
resultsum xs3 = [x+y+z | (x,y,z) <- xs3, let sumT=x+y+z in sumT>100]
BTW: The let in right of the | is local to the right part of |, you cannot use it left of |. However, you can use let as a standalone clause on the right side of | (thank chi) and then you can use it on the left side of | like
resultsum xs3 = [sumT | (x,y,z) <- xs3, let sumT=x+y+z, sumT>100]

Remove elements during infinite sequence generation

I found a great haskell solution (source) for generating a Hofstadter sequence:
hofstadter = unfoldr (\(r:s:ss) -> Just (r, r+s:delete (r+s) ss)) [1..]
Now, I am trying to write such a solution in F#, too. Unfortunately (I am not really familar to F#) I had no success so far.
My problem is, that when I use a sequence in F#, it seems not to be possible to remove an element (like it is done in the haskell solution).
Other data structures like arrays, list or set which allow to remove elements are not generating an infinite sequence, but operate on certain elements, only.
So my question: Is it possible in F# to generate an infinite sequence, where elements are deleted?
Some stuff I tried so far:
Infinite sequence of numbers:
let infinite =
Seq.unfold( fun state -> Some( state, state + 1) ) 1
Hofstadter sequence - not working, because there is no del keyword and there are more syntax errors
let hofstadter =
Seq.unfold( fun (r :: s :: ss) -> Some( r, r+s, del (r+s) ss)) infinite
I thought about using Seq.filter, but found no solution, either.
I think you need more than a delete function on sequence. Your example requires pattern matching on inifinite collections, which sequence doesn't support.
The F# counterpart of Haskell list is LazyList from F# PowerPack. LazyList is also potentially infinite and it supports pattern matching, which helps you to implement delete easily.
Here is a faithful translation:
open Microsoft.FSharp.Collections.LazyList
let delete x xs =
let rec loop x xs = seq {
match xs with
| Nil -> yield! xs
| Cons(x', xs') when x = x' -> yield! xs'
| Cons(x', xs') ->
yield x'
yield! loop x xs'
}
ofSeq (loop x xs)
let hofstadter =
1I |> unfold (fun state -> Some(state, state + 1I))
|> unfold (function | (Cons(r, Cons(s, ss))) ->
Some(r, cons (r+s) (delete (r+s) ss))
| _ -> None)
|> toSeq
There are a few interesting things here:
Use sequence expression to implement delete to ensure that the function is tail-recursive. A non-tail-recursive version should be easy.
Use BigInteger; if you don't need too many elements, using int and Seq.initInfinite is more efficient.
Add a case returning None to ensure exhaustive pattern matching.
At last I convert LazyList to sequence. It gives better interoperability with .NET collections.
Implementing delete on sequence is uglier. If you are curious, take a look at Remove a single non-unique value from a sequence in F# for reference.
pad's solution is nice but, likely due to the way LazyList is implemented, stack overflows somewhere between 3-4K numbers. For curiosity's sake I wrote a version built around a generator function (unit -> 'a) which is called repeatedly to get the next element (to work around the unwieldiness of IEnumerable). I was able to get the first 10K numbers (haven't tried beyond that).
let hofstadter() =
let delete x f =
let found = ref false
let rec loop() =
let y = f()
if not !found && x = y
then found := true; loop()
else y
loop
let cons x f =
let first = ref true
fun () ->
if !first
then first := false; x
else f()
let next =
let i = ref 0
fun () -> incr i; !i
Seq.unfold (fun next ->
let r = next()
let s = next()
Some(r, (cons (r+s) (delete (r+s) next)))) next
In fact, you can use filter and a design that follows the haskell solution (but, as #pad says, you don't have pattern matching on sequences; so I used lisp-style destruction):
let infinite = Seq.initInfinite (fun i -> i+1)
let generator = fun ss -> let (r, st) = (Seq.head ss, Seq.skip 1 ss)
let (s, stt) = (Seq.head st, Seq.skip 1 st)
let srps = seq [ r + s ]
let filtered = Seq.filter (fun t -> (r + s) <> t) stt
Some (r, Seq.append srps filtered)
let hofstadter = Seq.unfold generator infinite
let t10 = Seq.take 10 hofstadter |> Seq.toList
// val t10 : int list = [1; 3; 7; 12; 18; 26; 35; 45; 56; 69]
I make no claims about efficiency though!

Project Euler #4 using Haskell

I hope this works by just pasting and running it with "runghc euler4.hs 1000". Since I am having a hard time learning Haskell, can someone perhaps tell me how I could improve here? Especially all those "fromIntegral" are a mess.
module Main where
import System.Environment
main :: IO ()
main = do
args <- getArgs
let
hBound = read (args !! 0)::Int
squarePal = pal hBound
lBound = floor $ fromIntegral squarePal /
(fromIntegral hBound / fromIntegral squarePal)
euler = maximum $ takeWhile (>squarePal) [ x | y <- [lBound..hBound],
z <- [y..hBound],
let x = y * z,
let s = show x,
s == reverse s ]
putStrLn $ show euler
pal :: Int -> Int
pal n
| show pow == reverse (show pow) = n
| otherwise = pal (n-1)
where
pow = n^2
If what you want is integer division, you should use div instead of converting back and forth to Integral in order to use ordinary /.
module Main where
import System.Environment
main :: IO ()
main = do
(arg:_) <- getArgs
let
hBound = read arg :: Int
squarePal = pal hBound
lBound = squarePal * squarePal `div` hBound
euler = maximum $ takeWhile (>squarePal) [ x | y <- [lBound..hBound],
z <- [y..hBound],
let x = y * z,
let s = show x,
s == reverse s ]
print euler
pal :: Int -> Int
pal n
| show pow == reverse (show pow) = n
| otherwise = pal (n - 1)
where
pow = n * n
(I've re-written the lbound expression, that used two /, and fixed some styling issues highlighted by hlint.)
Okay, couple of things:
First, it might be better to pass in a lower bound and an upper bound for this question, it makes it a little bit more expandable.
If you're only going to use the first two (one in your previous case) arguments from the CL, we can handle this with pattern matching easily and avoid yucky statements like (args !! 0):
(arg0:arg1:_) <- getArgs
Let's convert these to Ints:
let [a, b] = map (\x -> read x :: Int) [arg0,arg1]
Now we can reference a and b, our upper and lower bounds.
Next, let's make a function that runs through all of the numbers between an upper and lower bound and gets a list of their products:
products a b = [x*y | x <- [a..b], y <- [x..b]]
We do not have to run over each number twice, so we start x at our current y to get all of the different products.
from here, we'll want to make a method that filters out non-palindromes in some data set:
palindromes xs = filter palindrome xs
where palindrome x = show x == reverse $ show x
finally, in our main function:
print . maximum . palindromes $ products a b
Here's the full code if you would like to review it:
import System.Environment
main = do
(arg0:arg1:_) <- getArgs
let [a, b] = map (\x -> read x :: Int) [arg0,arg1]
print . maximum . palindromes $ products a b
products a b = [x*y | x <- [a..b], y <- [x..b]]
palindromes = filter palindrome
where palindrome x = (show x) == (reverse $ show x)

How to make a random list using IO in Haskell

I'm trying to do a flocking simulation in order to better teach myself haskell. I'm running into trouble when trying to generate the initial state for the simulation which requires randomness. I'm trying to generate a list of Boids which all have random initial positions and directions.
In the main function I call this using
let numBoids = 10
rBoids <- randomBoids numBoids
And rBoids I indend to store in an IORef which I can then update every frame, which I think is the right way to do things?
And here is the code which fails:
-- Type for the flocking algorithm
data Boid = Boid {
boidPosition :: Vector2(GLfloat)
, boidDirection :: Vector2(GLfloat)
} deriving Show
randomBoids :: Int -> IO ([Boid])
randomBoids 0 = do
return []
randomBoids n = do
b <- randomBoid
bs <- (randomBoids (n-1))
return b : bs
randomBoid = do
pos <- randomVector
vel <- randomVector
return (Boid pos vel)
randomVector = do
x <- randomRIO(-1.0, 1.0)
y <- randomRIO(-1.0, 1.0)
return (Vector2 x y)
What actually fails is return b : bs. If I change this into return [b] it compiles. The error given is:
Couldn't match expected type `IO [Boid]' with actual type `[a0]'
In the expression: return b : bs
In the expression:
do { b <- randomBoid;
bs <- (randomBoids (n - 1));
return b : bs }
In an equation for `randomBoids':
randomBoids n
= do { b <- randomBoid;
bs <- (randomBoids (n - 1));
return b : bs }
I'm pretty lost here, and my understanding of the whole imperative-code-in-a-functional language (and monads) is shaky to say the least. Any help would be most appreciated!
Gangadahr is correct. I only wanted to mention that you can shorten your code a LOT:
import Control.Applicative
import Control.Monad
randomBoids n = replicateM n randomBoid
randomBoid = Boid <$> randomVector <*> randomVector
randomVector = Vector2 <$> randomRIO (-1, 1) <*> randomRIO (-1, 1)
The first function takes advantage of replicateM, which is a very useful function when you want to repeat a monadic action and collect the results. The latter two functions use Applicative style, which is enormously useful.
The reason you are getting the error is because return b : bs will make the compiler interpret it as (return b): bs To fix this, you can change the statement to return (b:bs). That will make the statement return an IO[Boid]
The typechecker is reading return x : xs as (return x) : xs. If you write return (x:xs) it will typecheck.

Resources