How would I get this piece of code to accept a list of strings and output a frame around the outside. I understand the concept but just cannot execute the code in the final frame function.
minusdots :: Int -> String
minusdots 1 = "-."
minusdots n
| n > 1 = "-." ++ (minusdots (n-1))
| otherwise = error "please enter greater than 1"
bar :: Int -> String
bar n
| even n = minusdots (div n 2)
| otherwise = (minusdots (div n 2)) ++ ['-']
frame :: [String] -> IO String
frame text = map putStrLn (bar m) ++ "\n" ++ textshown ++ "\n" ++ (bar m)
where
textshown = "- " ++ text ++ " -"
m = length textshown
I have worked on this all day and come up with this but there's still some bugs I need to work out 1. When I pass the border string into the frameM function, If I was to pass say "SS" is there any way I could make the S'S frame on top of each other,istead of side by side so the more letters i put into the first argument the bigger the total perimeter of the frame gets? heres what I've done:
minusdots :: Int -> String -> String
minusdots 1 a = a
minusdots n a
| n > 1 = a ++ (minusdots (n-1) a)
| otherwise = error "argument not addmissible"
bar :: String -> Int -> String
bar s n
| even n = minusdots (div n 2) s
| otherwise = (minusdots (div n 2) s) ++ s
frameM :: String -> String -> String
frameM a text = (bar a m) ++ "\n" ++ textshown ++ "\n" ++ (bar a m)
where
textshown = b ++ text ++ b
m = length textshown
b = a
I believe the type of your frame
should be frame :: String -> IO ()
— it takes a string a puts a "framed" version of it to stdout
. Then you don't need map putStrLn
and can just use putStrLn
.
Now, consider this line:
putStrLn (bar m) ++ "\n" ++ textshown ++ "\n" ++ (bar m)
you are calling putStrLn (bar m)
and then trying to append some stuff to the result of that (hint: use parentheses or $
).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.