I'm looking to convert a 2D list to a formatted string.
table :: [[Int]] -> String
Input: [[11,2,30],[4,555,9]]
Output: " 11 2 30 \n 4 555 6 \n"
11 2 30
4 555 9
Basically would need to be able to print out in a grid-shape and maintain formatting to account for the max value.
I know for simple lists I can map show [1,2,3,4] -> ["1","2","3","4"] according to ghci. That seems to keep it as a list though?
Not sure how I can traverse the 2D and keep concatenating as a string and adding \n as needed.
Playing at the REPL can help.
> :t '1'
'1' :: Char
> :t "1"
"1" :: [Char]
> ['1','2']
"12" :: [Char]
> :t concat
concat :: [[a]] -> [a]
> concat ( map show [1,2,3,4] )
.....
> concat [ show x | x <- [1,2,3,4] ]
.....
> concat [ " " ++ ( ensureWidth 9 (show x) ) | x <- [1,2,3,4] ]
.....
> :t replicate
replicate :: Int -> a -> [a]
> replicate 2 '1'
"11" :: [Char]
Now you need to write the function
ensureWidth w s = replicate n ' ' ++ s
but what n to use? You will need to know the length of s, for that. Function length can help.
Related
This question already has an answer here:
Haskell function :: [Name] -> [[(Name, Bool)]]
(1 answer)
Closed 4 years ago.
Having a list of ["P", "Q", "R" ...] I want to generate all possible list of [(String, Bool)] where on the left is a letter from the first array, and on the right is True or False. For example having ["P", "Q"] I want to obtain
: [[("P",True),("Q",True)],[("P",True),("Q",False)],[("P",False),("Q",True)],[("P",False),("Q",False)]]
I made it for the case where I only have ["P", "Q"] but I need to suport arbitrary number of letters. I tought I can generate for every letter L two pairs in an array like [(L,True),(L,False)] and do that for every letter and make all possible combinations of those arrays with one element from each array, but I don't know how to do it properly.
That's what I did for the list of length 2 of letters
envs :: [String] -> [[(String, Bool)]]
envs predicate = let
env = [(p,b) | p <- predicate, b <- [True, False]]
ps = filter (\(pred,val) -> pred == "P") env
qs = filter (\(pred,val) -> pred == "Q") env
in [[a,b] | a <- ps, b <- qs]
Introduce this function
cartProdn :: [a] -> Int -> [[a]]
cartProdn ls 2 = [[x, y] | x <- ls, y <- ls]
cartProdn ls n = [x : t | x <- ls, t <- cartProdn ls (n - 1)]
This gives all possible combinations of length n of a finite list (n > 1).
Then do
*Main> ls = ["P", "Q", "R"]
*Main> rs = [zip ls c | c <- cartProdn [True, False] (length ls)]
*Main> putStrLn $ unlines $ map show rs
[("P",True),("Q",True),("R",True)]
[("P",True),("Q",True),("R",False)]
[("P",True),("Q",False),("R",True)]
[("P",True),("Q",False),("R",False)]
[("P",False),("Q",True),("R",True)]
[("P",False),("Q",True),("R",False)]
[("P",False),("Q",False),("R",True)]
[("P",False),("Q",False),("R",False)]
note: you might want to write ls = "PQR".
Write the recursive function adjuster. Given a list of type
x, an int and an element of type x, either remove from the front of the
list until it is the same length as int, or append to the end of the list
until it is the same length as the value specified by the int.
expected:
adjuster [1..10] (-2) 2 -> *** Exception: Invalid Size
adjuster [1..10] 0 2 -> []
adjuster "apple" 10 ’b’ -> "applebbbbb"
adjuster "apple" 5 ’b’ -> "apple"
adjuster "apple" 2 ’b’ -> "le"
adjuster [] 3 (7,4) -> [(7,4),(7,4),(7,4)]
What i did:
adjuster (x:xs) count b
| count < 0 = error "Invalid Size"
| count == 0 = []
| count < length xs = adjuster xs (count-1) b
| otherwise = (adjuster xs (count-1) b):b
the error that I'm getting:
* Occurs check: cannot construct the infinite type: t ~ [t]
Expected type: [t]
Actual type: [[t]]
* In the expression: (adjuster xs (count - 1) b) : b
In an equation for `adjuster':
adjuster (x : xs) count b
| count < 0 = error "Invalid Size"
| count == 0 = []
| count < length xs = adjuster xs (count - 1) b
| otherwise = (adjuster xs (count - 1) b) : b
* Relevant bindings include
b :: [[t]] (bound at code01.hs:21:23)
adjuster :: [a] -> Int -> [[t]] -> [t] (bound at code01.hs:21:1)
I'm new in haskell.I'll really appreciate some help.
You are trying to construct a list within lists within lists and so on and so forth …
Why is this?
(:) :: a -> [a] -> [a]
The colon operator takes an element and a list of such elements as an argument and constructs a list from that (by prepending that element).
In your case if (adjuster ...) had type [a] then b must be of type [[a]], by line 4 which is the same as the end result, but line 3 says the type is [a] - which is different. This is what GHC tries to tell you.
How to fix it?
First of all, it is always a good advice to add a type signature to every top level function:
adjuster :: [a] -> Int -> a -> [a]
which should clean up your error-message and keep you honest, when implementing your function.
So how to fix this: - you could use b:adjuster xs (count-1) b but this would yield a result in the wrong order - so
choose a different operator: (++) and wrap the b inside a list.
| otherwise = (adjuster xs (count-1) b)++[b]
Now a few more hints:
turn on -Wall when you compile your file - this will show you that you missed the case of adjuster [] ...
using length is a relatively expensive operation - as it needs to traverse the full list to be calculated.
As an exercise - try to modify your function to not use length but only work with the base cases [] for list and 0 for count (here the function replicate might be helpful).
Here is another approach, without error handling
adjuster xs n v = tnr n $ (++) (replicate n v) $ tnr n xs
where tnr n r = take n $ reverse r
if you play with the signature, perhaps cleaner this way
adjuster n v = tnr . (++) (replicate n v) . tnr
where tnr = take n . reverse
Below I have defined a function that converts a list of base-3 digits to the corresponding numerical value. For example:
f "201" = (2 * 3^2) + (0 * 3^1) + (1 * 3^0) = 19
f "12" = 5
f "1202" = 47
f "120221" = 430
Here is a definition using comprehension:
f :: String -> Int
f str = sum (listToFinal (stringToTuples str))
Helper functions:
-- 1) converts "201" to "102"
reverse "str"
-- 2) converts "102" to 102
stringToInt :: String -> Int
stringToInt str = read str :: Int
-- 3) converts 102 to ['1','0','2']
intToList :: Int -> [Int]
intToList 0 = []
intToList x = intToList (x `div` 10) ++ [x `mod` 10]
-- 4) converts "201" to [(1,0),(0,1),(2,2)] using reverse, stringToInt, intToList
stringToTuples :: String -> [(Int,Int)]
stringToTuples str = zip (intToList (stringToInt (reverse str))) [0..]
-- 5) converts [(1,0),(0,1),(2,2)] to [1*3^0, 0*3^1, 2*3^2]
listToFinal :: [(Int,Int)] -> [Int]
listToFinal list = [ x * (3^y) | (x,y) <- list ]
Now I'd like to do it with recursion only (well, using basic & library functions too, of course).
An idea: I was thinking of taking the head of each element in the list and simply multiplying it with 3^(length of string - 1). The only problem is, with each recursive call the power of three would have to decrease by 1, e.g. given:
recursive_version "201" = (2 * 3^2) + (0 * 3^1) + (1 * 3^0)
How to implement this?
Here is a much simpler approach; note that, through the use of foldl, it's only "implicitly" recursive, though. For information, digitToInt is exported by Data.Char.
import Data.Char
import Data.List ( foldl' )
--- horner x xs : the value of polynomial 'xs' at point 'x'
horner :: Int -> [Int] -> Int
horner x = foldl' (\c1 c0 -> c1 * x + c0) 0
-- f s : the integer whose representation in base 3 is string 's'
f :: String -> Int
f = horner 3 . map digitToInt
When you define it recursively, the natural way to decrement the length is trimming the array from the head. For example:
base3 x = base3' x 0 where
base3' (d:ds) v = base3' ds $ v + d * 3 ^ length ds
base3' [] v = v
Just started learning Haskell a few days ago and I've come across a few issues. The first issue deals with printing a list of numbers. The desired behavior is as follows:
input: [1,2,3,4,5,6]
output: 1 2 3 | 4 5 6
So its a simple concept, I just need to output the elements of a list with the "|" symbol inserted between every three numbers, but I can't for the life of me figure it out. It seems like most of the stuff I've tried involves strings and even if I were able to get the list to strings such as ["1", "2", "3", ...] all the methods I've tried print the numbers each on their own line which is not what I need.
Any help would be greatly appreciated.
Using the split package (recently added to the Haskell Platform):
> import Data.List -- for intercalate
> import Data.List.Split -- for chunksOf
> intercalate " | " . map unwords . chunksOf 3 $ map show [1..7]
"1 2 3 | 4 5 6 | 7"
Relevant documentation: chunksOf, unwords, intercalate.
Here's one way.
import Data.List (cycle)
format :: Show a => [a] -> String
format = concat . zipWith (++) ("" : cycle [" ", " ", " | "]) . map show
This does has the drawback that the grouping into groups of three is hard-coded, but it is not too difficult to generalise.
You could do
threes [] = ""
threes xs = let (front,rest) = splitAt 3 xs in
unwords (map show front) ++
if null rest then "" else " | " ++ threes rest
giving
*Main> threes [1..10]
"1 2 3 | 4 5 6 | 7 8 9 | 10"
Functions I used:
splitAt :: Int -> [a] -> ([a], [a])
-- splitAt 2 "Hello Mum" = ("He","llo Mum")
unwords :: [String] -> String
-- unwords ["Hello","there","everyone"]
-- = "Hello there everyone"
null :: [a] -> Bool
null [] = True
null _ = False
The first part is the easiest, you need to convert the numbers to Strings,
format :: (Num a, Show a) => [a] -> String
format xs = result
where
strings = map show xs
does that. Then we need to split any list into chunks of three (more general, n) elements. splitAt splits a list into a front part of the desired number of elements - if the list is long enough - and a remainder. Iterating the procedure on the remainder, while that is not empty leads to the desired result.
chunk :: Int -> [a] -> [[a]]
chunk _ [] = []
chunk n xs = ys : chunk n zs
where
(ys, zs) = splitAt n xs
That is a recurring pattern, so there is a combinator for that, and we could also write
import Data.List (unfoldr)
chunk :: Int -> [a] -> [[a]]
chunk n = unfoldr split
where
split [] = Nothing
split xs = Just $ splitAt n xs
So we can continue our format,
format :: (Num a, Show a) => [a] -> String
format xs = result
where
strings = map show xs
chunks = chunk 3 strings
Then we need to insert a "|" between all chunks, that is done by intercalate from Data.List, and finally, concatenate all strings with spaces between them, that's what unwords does, so
format :: (Num a, Show a) => [a] -> String
format xs = result
where
strings = map show xs
chunks = chunk 3 strings
result = unwords $ intercalate "|" chunks
Or
format = unwords . intercalate "|" . chunk 3 . map show
I want to program a function that generates a String. The String contains only 1,0,s and S.
The numbers are binary numbers. Each number is separated through a s. And a number gives the length of the rest of the String. The capital S is the end of the String.
Examples:
func :: Integral a => a -> String
func 1
"1S"
func 3
"110s11s1S"
func 4
"1010s110s11s1S"
My problem is, that I don't know, how I can get the length of the tail ("s1S" -> tail, 11 -> head) and than get the new tail.
My new code:
>toBinary :: Integral a => a -> String
>toBinary 0 = []
>toBinary x
> | mod x 2 == 0 = '0' : toBinary (div x 2)
> | mod x 2 == 1 = '1' : toBinary (div x 2)
>zubinaer :: Integral a => a -> String
>zubinaer x = reverse (toBinary x)
>
>distan :: Integral a => a -> String
>distan n = if n > 0 then hilfsfunktion (n-1) "1S" else []
>
> where
> hilfsfunktion :: Integral a => a -> String -> String
> hilfsfunktion 0 s = s
> hilfsfunktion n s = hilfsfunktion (n-1) (zubinaer(length s + 1) ++ "s" ++ s )
Here my older code: http://hpaste.org/54863
I think you are tackling your problem from the wrong angle. In Haskell, one often thinks of lists. Actually, a String is just a list of Chars. Try to build your function from these bricks:
Write a function toBinary :: Integral a => a -> [Bool] that outputs a binary representation of its parameters. A 1 is True and a 0 is False
You can use map to turn the [Bool] into a String by replacing each boolean by a character 0 or 1.
You can use the syntax [1..n] to generate a list of integers from 1 to n. Use map to generate a list of binary representation strings.
Use intercalate from Data.List to create your string.
Since the tail is defined recursively (ex.: the "tail" of (f 4) is (f 3)) you can get the length of the tail by first getting the tail:
let the_tail = f (n-1) in
then calling the length function on it
length the_tail