patternMinor
Simple quotes app
Viewed 0 times
simplequotesapp
Problem
I created simple app that read
.
~ delimited txt file, convert it to [String] and display quotes on screen.- How would you improve this code? To be more Haskell like...
- in
splitStr(c/=)is faster than(/=c)by 20-50 ns. Why?
- Any other ways to clear screen in windows console app?
- If we compile this code as win console app, I assume
threadDelaypauses whole app not justoutQfunction. Right?
- Can someone point me in right direction how to refactor this code to use someting like JavaScripts setInterval or setTimeout.
- is there some easy way to catch
ctrl+cso I canshowCursoron exit?
.
import System.IO
import System.Random
import Control.Concurrent (threadDelay) -- microseconds
import System.Console.ANSI -- clearScreen
fileName = "quotes.txt"
oneSecond = 1000000
delay = 1 -- sec
splitStr _ [] = []
splitStr c xs = takeWhile (c/=) xs : splitStr c (drop 1 $ dropWhile (c/=) xs)
--clear = putStr "\ESC[2J" -- not working on windows
outQ list l sec g = do
clearScreen
setCursorPosition 0 0 -- row col
let (index, gen') = randomR (0, l) g
putStrLn $ list !! index
threadDelay $ sec * oneSecond
outQ list l delay gen' -- works
main :: IO ()
main = do
setTitle "Quotes"
hideCursor -- catch ctrl+c for showCursor
gen <- newStdGen
str <- readFile fileName
let qlist = splitStr '~' str
let len = length qlist -1
outQ qlist len delay genSolution
I'm going to talk about your
First, it's almost the same as
-
Replace
with
But let's suppose you can't use the split package for some reason, and try to improve your
We can use
splitStr function.First, it's almost the same as
splitOn from Data.List.Split in the split package.- Run
cabal install split
- Add
import Data.List.Splitat the start of your code
-
Replace
let qlist = splitStr '~' strwith
let qlist = splitOn "~" strBut let's suppose you can't use the split package for some reason, and try to improve your
splitStr.splitStr :: Eq a => a -> [a] -> [[a]]
splitStr _ [] = []
splitStr c xs = takeWhile (c/=) xs : splitStr c (drop 1 $ dropWhile (c/=) xs)We can use
span instead of takeWhile and dropWhile. This is clearer and also more efficient as we only have to traverse the list once instead of twice.splitStr :: Eq a => a -> [a] -> [[a]]
splitStr _ [] = []
splitStr c xs = ys : splitStr c (drop 1 zs)
where (ys, zs) = split (c/=) xsCode Snippets
let qlist = splitStr '~' strlet qlist = splitOn "~" strsplitStr :: Eq a => a -> [a] -> [[a]]
splitStr _ [] = []
splitStr c xs = takeWhile (c/=) xs : splitStr c (drop 1 $ dropWhile (c/=) xs)splitStr :: Eq a => a -> [a] -> [[a]]
splitStr _ [] = []
splitStr c xs = ys : splitStr c (drop 1 zs)
where (ys, zs) = split (c/=) xsContext
StackExchange Code Review Q#13888, answer score: 4
Revisions (0)
No revisions yet.