How to print out 2d array haskell - haskell

I would like to print out 2d array e.g.
data a = b [[a]]
instances Show a where
show (b array) = "Array:\n" ++ show array
array = [[(1, 2), (3, 4)],[(5, 6), (7, 8)]]
(I hope this pseudocode is readable)
in that way:
[(1, 2), (3, 4)]\n
[(5, 6), (7, 8)]
the only result I get is:
[[(1, 2), (3, 4)], [(5, 6), (7, 8)]]
I need to use instance Show.

I found an interesting link on StackOverflow about the overloading show function for list type.
Code:
{-# LANGUAGE FlexibleInstances #-}
module Main where
array = [[(1, 2), (3, 4)],[(5, 6), (7, 8)]]
main = putStrLn $ Main.show array
instance {-# OVERLAPPING #-} Show [[a]] where
show (a:x) = Prelude.show a ++ "\n" ++ Main.show x
show [] = ""
Compilation output (unfortunately not warning-free):
[1 of 1] Compiling Main ( main.hs, main.o )
main.hs:6:30: warning: [-Wmissing-methods]
* No explicit implementation for
either `showsPrec' or `Prelude.show'
* In the instance declaration for `Show [[a]]'
|
6 | instance {-# OVERLAPPING #-} Show [[a]] where
| ^^^^^^^^^^
Linking main ...
Output:
[(1,2),(3,4)]
[(5,6),(7,8)]

Related

Haskell -- Generate Coordinates From Ends of the Path

I have an input of [ ( (Int,Int) , (Int,Int) ) ] which is the coordinate of the ends of the path. All paths run either horizontally (same y-value for both ends) or vertically (same x-value for both ends).
So I want to write a function that generates all the coordinates of the path from the input.
For example, the input pair of ends is [((0, 0), (0, 3)), ((0, 2), (2, 2))](this is two paths), the output of the function I need is [[(0, 0), (0, 1), (0, 2), (0, 3)], [(0, 2), (1, 2), (2, 2)]]
getPaths :: [ ( (Integer,Integer) , (Integer,Integer) ) ] -> [[(Integer,Integer)]]
getPaths [((xa, ya), (xb, yb))]
| xa == xb : [(xa, yb + 1) | yb < ya]++
| xa == xb : [(xa, ya + 1) | ya < yb]++
| ya == yb : [(xa + 1, ya) | xa < xb]++
| ya == yb : [(xb + 1, ya) | xb < xa]++
I'm not sure if its right, could anyone have a look at it?
I think it is better to first make a function that works with a single pair of coordinates:
path :: ((Int, Int), (Int, Int)) -> [(Int, Int)]
path = …
then getPaths is just a mapping of this:
getPaths :: [((Int, Int), (Int, Int))] -> [[(Int, Int)]]
getPaths = map path
as for the path, you can make use of ranges, indeed [x₁ .. x₂] will produce all (integral) values between x₁ and x₂ (both inclusive).
The function thus can be constructed with list comprehension with:
path :: ((Int, Int), (Int, Int)) -> [(Int, Int)]
path ((x₁, y₁), (x₂, y₂)) = [ … | … <- …, … <- … ]
where you still need to fill in the … parts.

Haskell filtering data

I want to be able to filter the below data so I can find specific data for example if I wanted to find an item with only apples it would look similar to this output: [("apple","crate",6),("apple","box",3)]
fruit :: [(String, String, Int)]
fruit = [("apple", "crate", 6), ("pear", "crate", 5), ("mango", "box", 4),
("apple", "box", 3), ("banana", "box", 5), ("pear", "box", 10), ("apricot",
"box", 4), ("peach", "box", 5), ("walnut", "box", 4), ("blueberry", "tray", 10),
("blackberry", "tray", 4), ("watermelon", "piece", 8), ("marrow", "piece", 7),
("hazelnut", "sack", 2), ("walnut", "sack", 4)]
first :: (a, b, c) -> a
first (x, _, _) = x
second :: (a, b, c) -> b
second (_, y, _) = y
third :: (a, b, c) -> c
third (_, _, z) = z
A couple of alternatives:
filter ((=="apple") . first) fruit
[ f | f#("apple",_,_) <- fruit ]
The first one exploits your first projection, checking whether its result is equal to "apple".
The second one instead exploits list comprehensions, where elements that fail to pattern match are discarded.
Perhaps an even more basic approach is using a lambda abstraction and equality.
filter (\(s,_,_) -> s == "apple") fruit

Recursive function

Let S be the subset of the set of ordered pairs of integers defined recursively by
Basis step: (0, 0) ∈ S.
Recursive step: If (a,b) ∈ S,
then (a,b + 1) ∈ S, (a + 1, b + 1) ∈ S, and (a + 2, b + 1) ∈ S.
List the elements of S produced by the first four application
def subset(a,b):
base=[]
if base == []:
base.append((a,b))
return base
elif (a,b) in base:
base.append(subset(a,b+1))
base.append(subset(a+1,b+1))
base.append(subset(a+2,b+1))
return base
for number in range(0,5):
for number2 in range(0,5):
print(*subset(number,number2))
The output is
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(1, 4)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 0)
(3, 1)
(3, 2)
(3, 3)
(3, 4)
(4, 0)
(4, 1)
(4, 2)
(4, 3)
(4, 4)
But the correct answer is more than what I got.
(0, 1), (1, 1), and (2, 1) are all in S. If we apply the recursive step to these we add (0, 2), (1, 2), (2, 2), (3, 2), and (4, 2). The next round gives us (0, 3), (1, 3), (2, 3), (3, 3), (4, 3), (5, 3), and (6, 3). And a fourth set of applications adds (0,4), (1,4), (2,4), (3,4), (4,4), (5,4), (6,4), (7,4), and (8,4).
What did I do wrong with my code?
Is this what you want ? Based on the result you wanted :
def subset(a):
#Returns a list that contains all (i, a + 1) from i = 0 to i = (a + 1) * 2 + 1
return [(i, a + 1) for i in range((a + 1) * 2 + 1)]
setList = []
for i in range(4):
setList += subset(i) #Fill a list with subset result from i = 0 -> 3
print(setList)
If you want to use a recursive function, you can do that too :
def subset(a, b):
if a < b * 2:
#Returns a list that contains (a, b) and unzipped result of subset(a + 1, b)
#Otherwise it would add a list in the list
return [(a, b), *subset(a + 1, b)]
else:
return [(a, b)] #If deepest element of recursion, just return [(a, b)]
setList = []
for i in range(5):
setList += subset(0, i)
print(setList)

Haskell - Printing elements of a tuple

I know that I can print line-by-line the tuples in a list of tuples like this:
Prelude> mapM_ print [(1, 1), (2, 4), (3, 9)]
(1,1)
(2,4)
(3,9)
But suppose that I want to output this to a CSV file and I want to output this
Prelude> ??? [(1, 1), (2, 4), (3, 9)]
1,1
2,4
3,9
How can I do that?
Try this:
showTup :: (Show a, Show b) => (a,b) -> String
showTup (a,b) = (show a) ++ "," ++ (show b)
λ> mapM_ (putStrLn . showTup) [(1,1), (2,4), (3,9)]
1,1
2,4
3,9
Since Haskell is so awesome, you can just write a function that converts a tuple to a string, and since print is just (putStrLn . show) you can substitute show by your own function.

Haskell parMap and parallelism

I have an implementation of Conway's Game of Life. I want to speed it up if possible by using parallelism.
life :: [(Int, Int)] -> [(Int, Int)]
life cells = map snd . filter rules . freq $ concatMap neighbours cells
where rules (n, c) = n == 3 || (n == 2 && c `elem` cells)
freq = map (length &&& head) . group . sort
parLife :: [(Int, Int)] -> [(Int, Int)]
parLife cells = parMap rseq snd . filter rules . freq . concat $ parMap rseq neighbours cells
where rules (n, c) = n == 3 || (n == 2 && c `elem` cells)
freq = map (length &&& head) . group . sort
neigbours :: (Int, Int) -> [(Int, Int)]
neighbours (x, y) = [(x + dx, y + dy) | dx <- [-1..1], dy <- [-1..1], dx /= 0 || dy /= 0]
in profiling, neighbours accounts for 6.3% of the time spent, so while small I expected a noticable speedup by mapping it in parallel.
I tested with a simple function
main = print $ last $ take 200 $ iterate life fPent
where fPent = [(1, 2), (2, 2), (2, 1), (2, 3), (3, 3)]
and compiled the parallel version as
ghc --make -O2 -threaded life.hs
and ran it as
./life +RTS -N3
it turns out that the parallel version is slower. Am I using parMap incorrectly here? is this even a case where parallelism can be used?
I don't think you're measuring right. Your parLife is indeed a bit faster than life. In fact, on my machine (Phenom X4, 4 core,) the former only takes about 92.5% of the time the latter does, which considering you're saying you're expecting only a 6% improvement is quite good.
What is your benchmarking setup? Have you tried using criterion? Here's what I did:
import Criterion
import Criterion.Main
-- your code, minus main
runGame f n = last $ take n $ iterate f fPent
where fPent = [(1, 2), (2, 2), (2, 1), (2, 3), (3, 3)]
main = defaultMain
[ bench "No parallelism 200" $ whnf (runGame life) 200
, bench "Parallelism 200" $ whnf (runGame parLife) 200 ]
Compiled with ghc --make -O2 -o bench and ran with ./bench -o bencht.hmtl +RTS -N3.
Here's the detailed result of the report.

Resources