Haskell: Print Int from list one by one - list

I've got a short question regarding something I want to do in Haskell.
What I basically aim to achieve is to make a list of integers from 1 to a specific value y. Like [1..y], and the print this list with spaces between each number
Let's say i have [1..8]
My desired output is ("_" represents spaces):
_1_2_3_4_5_6_7_8
I have played a little bit with different things but without any luck
This is basically what Iv' got so far
printLst :: [Int] -> String
printLst (x:xs) = " " ++ putStr (show x) >> printLst xs
I've been searching around the web to find any solution to this, but I have not found anything that helps me do this.
Help is greatly appreciated

First, define a function which converts an Int to a String, then prepends a space to the result.
\x -> ' ' : show x
Now map this over your list:
> map (\x -> ' ' : show x) [1..8]
[" 1"," 2"," 3"," 4"," 5"," 6"," 7"," 8"]
Now we just need to concatenate all the strings into one:
> concat (map (\x -> ' ' : show x) [1..8])
" 1 2 3 4 5 6 7 8"
This can be simplied using the concatMap function:
> concatMap (\x -> ' ':show x) [1..8]
" 1 2 3 4 5 6 7 8"
which forms the basis for the Monad instance for lists:
> [1..8] >>= (\x -> ' ' : show x)
" 1 2 3 4 5 6 7 8"
or even more briefly, using function composition
> [1..8] >>= (' ' :) . show
" 1 2 3 4 5 6 7 8"
Once you have the final string, now you can worry about printing it.
> putStrLn $ [1..8] >>= (' ' :) . show
1 2 3 4 5 6 7 8

Well you are confusing things here, first of all:
putStr :: String -> IO ()
And you are returning a String, so no need to use that. Also, you have no patter for [] and singleton list, you can add them to get a better output like this:
printLst :: [Int] -> String
printLst [] = ""
printLst [x] = (show x)
printLst (x:xs) = (show x) ++ " " ++ printLst xs
If you want to use IO () function, use it in the main function:
main = do
putStrLn (printLst [1..8])

This is a list processing problem. For an empty list, we can return the empty string, for a non-empty list, we can first yield a space, followed by the show of that item, and then recurse on the rest of that list, like:
prefixSpace :: Show a => [a] -> String
prefixSpace [] = ""
prefixSpace (x:xs) = ' ' : show x ++ prefixSpace xs
Or as a "fold" pattern:
prefixSpace :: Show a => [a] -> String
prefixSpace = foldr (\x -> ((' ' : show x) ++)) ""
This will not print the string. For that you need putStrLn :: String -> IO (), but as the signature indicates, if you putStrLn some_string, you work with an IO ().

Related

How to check if length of a list is not equal to length of a list within a list in haskell

Hi Guys I am trying to check whether the length of a list is not equal to length of a list within a list using haskells length function and pattern matching
This is the function i have and its type:
func :: [String] -> [[String]] -> String
where the return string is either "Error different lengths found" OR
"Lengths are the same"
This is what i would input and the expected output see below:
["Planet", "City"] [["Jupiter", "Earth"], ["Berlin", "Madrid", "Krakow"] ]
Output should be "Error different lengths found" due to ["Berlin", "Madrid", "Krakow"] being of size 3 where as ["Planet", "City"] is of size 2
bit unsure how to do this and would appreciate any help!
Something like this would check it in linear time.
compLength :: [String] -> [[String]] -> String
compLength s = go (length s)
where go _ [] = "All Good! Hurray!"
go n (y:ys)
| n /= length y = "Error different lengths found" ++ " [" ++ unwords y ++ "]"
| otherwise = go n ys
I think this gives you the base and the necessary information to tailor the output to your exact needs.
You can write a helper function to check if two lists have the same length, so you can implement a function:
sameLength :: [a] -> [a] -> Bool
sameLength … = …
When you have implemented such function, it is only a matter to check if all sublists have the same length. We can do this with all :: Foldable f => (a -> Bool) -> f a -> Bool:
func :: [a] -> [[a]] -> Bool
func xs yss
| all (sameLength xs) yss = "Lengths are the same"
| otherwise = "Error different lengths found"

How to print elements of A list of Ints in one line in Haskell

I need to print a list of integers in Haskell in one line only separated by space...
Like , I would want to print
[6,5,4,7,3,9]
in this manner
6 5 4 7 3 9
I used the Map_ function but that prints all the elements in different lines.
You can try this
main = putStrLn . unwords . map show $ [1,2,3,4]
Instead of unwords you could also use intercalate " " for a more generic function.
You can define a customized print function, which accepts a parameter of separator:
type Separator = String
cPrint :: Show a => Separator -> a -> IO ()
cPrint sep v = putStr $ show v ++ sep
ghci> mapM_ (cPrint " ") [6,5,4,7,3,9]
6 5 4 7 3 9 ghci>

Gap function that returns the integer distance between first appearance of two elements in a list using either foldl or foldr.(Haskell)

the type is defined as follows:
gap :: (Eq a) => a -> a -> [a] -> Maybe Int
I have been stuck on this problem for more than an hour and have no idea how to approach the problem. I am aware that it requires the use of fold and am familiar with that topic.
Please take into consideration that either foldl or foldr must be used.
The output when called ought to look like this
gap 3 8 [1..10]
=Just 5
gap 8 3 [1..10]
=Nothing
gap 'h' 'l' "hello"
=Just 2
gap 'h' 'z' "hello"
=Nothing
You might dropWhile the list until you find the starting element and then fold from the right, starting with Nothing, replacing that with Just 1 once you hit the end element, and fmaping +1 to the accumulator. In code:
gap :: Eq a => a -> a -> [a] -> Maybe Int
gap from to xs = case dropWhile (/= from) xs of
[] -> Nothing
(_:rest) -> gap' to rest
gap' :: Eq a => a -> [a] -> Maybe Int
gap' to = foldr f Nothing
where f x acc | x == to = Just 1
| otherwise = (+1) <$> acc
The nice thing is that it works correctly if you have several occurences of the elements in your sequence:
*Main> gap 3 8 $ [1..10] ++ [1..10]
Just 5
*Main> gap 3 8 [1, 2, 3, 3, 3, 8]
Just 3
Maybe my solution isn't nice, but it works
import Control.Monad
import Data.Function
import Data.Foldable
(...) = (.) . (.)
gap x y = liftA2 ((guard . (> 0) =<<) ... liftA2 (subtract `on` fst))
(find ((==x) . snd)) (find((==y) . snd)) . zip [0..]

How to print part of a list on a new line in Haskell

This may be a silly question, but I'm very new to Haskell. (I just started using it a couple of hours ago actually.)
So my problem is that I have a list of 4 elements and I need to print two on one line and two on a new line.
Here's the list:
let list1 = ["#", "#", "#", "#"]
I need the output to look like this:
##
##
I know that i could use the following to print every element on a new line:
mapM_ putStrLn list1
but I'm not sure how to adapt this for only printing part of the list on a new line.
You want something like Data.Text.chunksOf for arbitrary lists, which I've never seen anywhere so I always reimplement it.
import Data.List (unfoldr)
-- This version ensures that the output consists of lists
-- of equal length. To do so, it trims the input.
chunksOf :: Int -> [a] -> [[a]]
chunksOf n = unfoldr (test . splitAt n) where
test (_, []) = Nothing
test x = Just x
Then we can take your [String] and turn it into [[String]], a list of lists each corresponding to String components of a line. We map concat over that list to merge up each line from its components, then use unlines to glue them all together.
grid :: Int -> [String] -> String
grid n = unlines . map concat . chunksOf n
Then we can print that string if desired
main :: IO ()
main = putStrLn $ grid 2 list1
Edit: apparently there is a chunksOf in a fairly popular library Data.List.Split. Their version is to my knowledge identical to mine, though it's implemented a little differently. Both of ours ought to satisfy
chunksOf n xs ++ chunksOf n ys == chunksOf n (xs ++ ys)
whenever length xs `mod` n == 0.
You can do:
mapM_ putStrLn [(take 2 list1), (drop 2 list1)]
where take and drop return lists with the expected number of elements. take 2 takes two elements and drop 2 drops the first two elements.
Looking at tel link Data.List.Split, another solution can be built on using chop.
Define as follow into the lib,
chop :: ([a] -> (b, [a])) -> [a] -> [b]
chop _ [] = []
chop f as = b : chop f as'
where (b, as') = f as
Then following's simeon advice we end with this one liner,
let fun n = mapM_ putStrLn . chop (splitAt n)
chop appears to be a nice function, enough to be mentioned here to illustrate an alternative solution. (unfoldr is great too).
Beginner attempt:
myOut :: [String] -> IO ()
myOut [] = putStr "\n"
myOut (x:xs) =
do if x=="#"
then putStrLn x
else putStr x
myOut xs
ghci>myOut ["#", "#", "#", "#"]
##
##
ghci>

How to print a block of data in Ocaml?

I would like to print some rectangles one by one in a terminal like that:
4 5 7 8
2 5
3 : bool 6 : int
Which represents that, given an array a, the zone from a([2,3], [4,5]) is bool and the zone from a([5,6], [7,8]) is int.
So the key is to print a block of data in several rows, instead of 1 row as default. Does anyone know how to realize that in Ocaml?
Thank you very much!
Basically, there are two approaches possible:
accumulate your two-dimensional output and use a specialized print function which rearranges the strings in a way you wish
print to a medium with 2D capabilities like terminal or GUI element (to play with terminal screen, one can use a binding to ncurses)
The first approach is more universal and remains functional in spirit. For example:
let item1 =
[" 4 5 "
;"2 "
;"3 : bool "
]
let item2 =
[" 7 8 "
;"5 "
;"6 : int "
]
let transpose ll =
let rec pick_one ll =
match ll with
| [] -> []
| [] :: _ -> []
| _ ->
let tear (reaped, rest) l =
match l with
| [] -> assert false
| hd :: tl -> (hd :: reaped, tl :: rest)
in
let (reaped, rest) = List.fold_left tear ([], []) ll in
(reaped :: (pick_one rest))
in
pick_one ll
let multiline_print items =
let by_lines = transpose items in
let show_line line = List.iter print_string line; print_endline "" in
List.iter show_line by_lines
let _ = multiline_print [item1; item2]
Depending on your needs, you may build printf-like functionality around this.
You need to route through a "layout engine" the strings produced by the functions in your new Printf-like module.