Haskell - Printing elements of a tuple - haskell

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.

Related

How to print out 2d array 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)]

How to define a strict existential type?

I want to use Haskell's existential types (http://www.haskell.org/haskellwiki/Existential_type) in a strict context. I took the example from the haskell-wiki and tried to create a strict heterogeneous map with it. It's required that the map and it's values get fully evaluated.
I defined 3 types to test this. The first one is just a simple strict map. The second type is a heterogeneous map using existential types. The third type is like the second, but adds NFData constraints.
While the first simple example is truly strict and gets fully evaluated, the other ones are not. Even the third type, using deepseq, seems not to be fully evaluated.
My questions are:
How do i define such a heterogeneous type in a strict way?
If it's not possible - Why not? Is there a way to work around this?
Example source
{-# LANGUAGE ExistentialQuantification #-}
import GHC.AssertNF
import Control.DeepSeq
import Data.Map.Strict
-- 1) simple container
data Obj a = Obj a
-- using a smart constructor here to ensure arbitrary values are strict
mkObj :: a -> Obj a
mkObj a = Obj $! a
-- using a special String constructor to ensure Strings are always
-- fully evaluated in this example
mkString :: String -> String
mkString x = force x
xs :: Map Int (Obj String)
xs = fromList [ (1, mkObj . mkString $ "abc")
, (2, mkObj . mkString $ "def")
, (3, mkObj . mkString $ "hij")
]
-- 2) container using existential quantification
data Obj2 = forall a. (Show a) => Obj2 a
-- using the smart constructor here has no effect on strictness
mkObj2 :: Show a => a -> Obj2
mkObj2 a = Obj2 $! a
xs2 :: Map Int Obj2
xs2 = fromList [ (1, mkObj2 1)
, (2, mkObj2 . mkString $ "test")
, (3, mkObj2 'c')
]
-- 3) container using existential quantification and deepseq
data Obj3 = forall a. (NFData a, Show a) => Obj3 !a
instance NFData Obj3 where
-- use default implementation
mkObj3 :: (NFData a, Show a) => a -> Obj3
mkObj3 a = Obj3 $!! a
xs3 :: Map Int Obj3
xs3 = fromList [ (1, mkObj3 (1::Int))
, (2, mkObj3 . mkString $ "abc")
, (3, mkObj3 ('c'::Char))
]
-- strictness tests
main :: IO ()
main = do
putStr "test: simple container: "
(isNF $! xs) >>= putStrLn . show
assertNF $! xs
putStr "test: heterogeneous container: "
(isNF $! xs2) >>= putStrLn . show
assertNF $! xs2
putStr "test: heterogeneous container with NFData: "
(isNF $!! xs3) >>= putStrLn . show
assertNF $!! xs3
return ()
GHCI output
test: simple container: True
test: heterogeneous container: False
Parameter not in normal form: 1 thunks found:
let x1 = Tip()
in Bin (I# 2) (Obj2 (_sel (_bh (...,...))) (C# 't' : C# 'e' : ... : ...)) (Bin (I# 1) (Obj2 (D:Show _fun _fun _fun) (S# 1)) x1 x1 1) (Bin (I# 3) (Obj2 (D:Show _fun _fun _fun) (C# 'c')) x1 x1 1) 3
test: heterogeneous container with NFData: False
Parameter not in normal form: 1 thunks found:
let x1 = _ind ...
x2 = Tip()
in _bh (Bin (I# 2) (Obj3 (_bh (_fun x1)) (_sel (_bh (...,...))) (C# 'a' : C# 'b' : ... : ...)) (Bin (I# 1) (Obj3 (_ind _fun) (D:Show _fun _fun _fun) (I# 1)) x2 x2 1) (Bin (I# 3) (Obj3 x1 (D:Show _fun _fun _fun) (C# 'c')) x2 x2 1) 3)
Believe it or not, but all three tests of yours are strict! In the sense of, the "heterogeneos objects" you're storing are evaluated before being put in the container objects.
What's not strict is just the implementation of the existential. The thing is, Haskell doesn't really have existentials, they're emulated by record types which store the type class dictonaries. In you case of just a Show constraint, that basically means you're not storing the object but only its result of show, which is a string. But GHC can't know you want that string to be evaluated strictly; in fact it would usually be a bad idea because show may typically be much more expensive than deep-evaluating an object. So the show is left to be evaluated when you call it, which is quite fine IMO.
If you do want to evaluate the show strictly, the only way to be sure is make the record transformation explicit. In your example, that's trivial:
newtype Obj2 = Obj2 { showObj2 :: String }
mkObj2 :: Show a => a -> Obj2
mkObj2 = (Obj2 $!) . show
Note that datatypes such as
data Obj2 = forall a. (Show a) => Obj2 a
data Obj3 = forall a. (NFData a, Show a) => Obj3 !a
actually store the class dictionaries as well as the data, so for example, Obj2
actually has two fields. Your smart constructor forces the data field to be strict,
but you have no direct control over the dictionary. I doubt that forcing or not-forcing
the dictionary will make much difference in practice, but you may be able to trick the
compiler into doing so. For example, the following variant seems to work for me for Obj2:
mkObj2 :: Show a => a -> Obj2
mkObj2 a = showsPrec 0 a `seq` (Obj2 $! a)
You can also see that the following two will "work":
data Obj2a = forall a. Obj2a a
mkObj2a a = Obj2a $! a
xs2a :: Map Int Obj2a
xs2a = fromList [ (1, mkObj2a 1)
, (2, mkObj2a . mkString $ "test")
, (3, mkObj2a 'c')
]
data Obj2b = forall a. Obj2b (a -> String) a
mkObj2b :: Show a => a -> Obj2b
mkObj2b a = (Obj2b $! show) $! a
xs2b :: Map Int Obj2b
xs2b = fromList [ (1, mkObj2b 1)
, (2, mkObj2b . mkString $ "test")
, (3, mkObj2b 'c')
]

Foldr issues (Haskell)

I'm trying to convert from a table which is of type ([Char, Int]) to a string tab2str :: Table -> String (that follows some specific formatting patterns.)
I'm using foldr (as the title implies) but I'm having some issues getting the exact function to work - i.e. It errors. My function looks like this:
tab2str xs = foldr (++) ' ' $ map (\char count -> show char ++ ':' ++ show count ++ '\n') xs
The output should be each letter in the table, a colon, then \n. So a test might be:
tab2str test1 == "F: 1\no: 1\nl: 1\nd: 1\nr: 1\n"
where
test1 == [(F, 1), (o, 1), (l, 1), (d, 1), (r, 1)]
Any help gratefully received.
After minimal corrections this typechecks:
tab2str xs = foldr (++) " " $ map (\(char, count) -> show char ++ ":" ++ show count ++ "\n") xs
– but produces not quite what you want.
You'll probably like this better:
tab2str table = concat $ map formatRow table
where formatRow (char, count) = [char] ++ ": " ++ show count ++ "\n"
Then your test example:
ghci> let test1 = [('F', 1), ('o', 1), ('l', 1), ('d', 1), ('r', 1)]
ghci> tab2str test1
"F: 1\no: 1\nl: 1\nd: 1\nr: 1\n"
ghci> putStr $ tab2str test1
F: 1
o: 1
l: 1
d: 1
r: 1
ghci>

Comparing and counting string correlations with Haskell

I'm working on a pretty complicated (complicated for me, at least) function that I'd like to use to count the number of times a word in a list corresponds with a word in a database.
An example using random words:
let input = [("InputName", ["dog", "cat", "cat"...]), ...]
let database = ["dog", "cat", "badger"...]
After several hours of mental gymnastics, I came up with this hideous function that almost works. I've simplified it so it'll make sense in the context of this example:
findMatches input database = [ (snd x, wordCount (snd x)) | x <- input ]
where
wordCount ys = sum[ if y `elem` database then 1 else 0 | y <- ys ]
My goal, my hope, my wish would be to have an output that reads:
[("dog", 1), ("cat", 2), ("badger", 0)]
Any suggestions or nudges in the right direction would be appreciated.
EDIT
I finally made a function that works. catWordCount counts the number of times a database entry appears in an input. I'm working on a better implementation using fold.
let input = words "5 4 10 0 1 9 1"
let database = [("C1", words "1 2 3 4 5"), ("C2", words "6 7 8 9 10")]
catwordCount input database
catWordCount fs zs = [ (fst f, inputSearch (snd f)) | f <- fs ]
where
inputSearch gs = [ (g, wordCount [g]) | g <- gs ]
wordCount hs = sum[ if h == z then 1 else 0 | h <- hs, z <- zs ]
And the output:
(["C1", [("1",2),("2",0),("3",0),("4",1),("5",1)])
(["C2", [("6",0),("7",0),("8",0),("9",1),("10",1)])
You can keep a Map of counts that you update for each item. Since you don't want to include items from the input list that are not in the database, if I understood correctly,
alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a
is a good way to do that. The supplied key k is looked up, and if it's present, the argument to the update function will we Just value, otherwise it will be Nothing. If the result of the update function is Nothing, the key will be deleted from the Map (or not added, if it wasn't present), if the result is Just something, the key will be associated with something in the altered Map.
So you start with a Map mapping every item to 0,
m0 :: Map String Int
m0 = fromList $ zip database (repeat 0)
to update, you want to increment the count if the item is in database, and not change anything otherwise,
incr :: Maybe Int -> Maybe Int
incr (Just n) = Just (n+1)
incr Nothing = Nothing
or, shorter, incr = fmap (+1) using the Functor instance of Maybe.
Then the resulting map is simply
finalMap :: Map String Int
finalMap = foldl (flip $ alter incr) m0 $ snd input
and if you want a list rather than a Map, just call assocs or toList on finalMap.
It might not be exactly what you are looking for, but try this:
import Data.List
countMatches :: [(String, [String])] -> [(String, Int)]
countMatches = map (\l -> (head l, length l)) . group . sort . concat . map snd
Hopefully the function compositions are not too confusing. I'll go over it step by step. Say you run this function with input
[("", ["a", "b"]), ("", ["b", "c", "x", "a"]), ("", ["y", "b", "z"])]
After map snd it is
[["a", "b"], ["b", "c", "x", "a"], ["y", "b", "z"]]
After concat,
["a", "b", "b", "c", "x", "a", "y", "b", "z"]
After sort,
["a", "a", "b", "b", "b", "c", "x", "y", "z"]
After group,
[["a", "a"], ["b", "b", "b"], ["c"], ["x"], ["y"], ["z"]]
And finally map (\l -> (head l, length l)) produces
[("a", 2), ("b", 3), ("c", 1), ("x", 1), ("y", 1), ("z", 1)]

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