https://wiki.haskell.org/api.php?action=feedcontributions&user=Psybur&feedformat=atomHaskellWiki - User contributions [en]2020-05-30T06:55:39ZUser contributionsMediaWiki 1.27.4https://wiki.haskell.org/index.php?title=Simple_RWST_use&diff=62281Simple RWST use2018-01-09T19:47:11Z<p>Psybur: </p>
<hr />
<div>RWST on IO example. Inspired by [[Simple_StateT_use]].<br\><br />
Guess the number between 1 and 10 within a certain number of tries.<br\><br />
Guesses are entered via stdin.<br />
<br />
Reader: Env is max tries.<br\><br />
Writer: Guesses are logged to a String.<br\><br />
State: Number of guesses in session.<br\><br />
IO: Get next guess from stdin.<br\><br />
<br />
<haskell><br />
import System.Random<br />
import Control.Monad.RWS<br />
<br />
main = do answer <- getStdRandom (randomR (1,10)) -- think of a number<br />
let maxTries = 5<br />
putStrLn "I'm thinking of a number between 1 and 10, can you guess it?"<br />
putStrLn $ "You've got " ++ show maxTries ++ " tries!"<br />
(guesses,log) <- execRWST (guessSession answer) maxTries 0<br />
putStrLn $ "Finished in " ++ (show guesses) ++ " tries."<br />
putStrLn $ "Guesses: " ++ show log<br />
<br />
guessSession :: Int -> RWST Int [Int] Int IO ()<br />
guessSession answer =<br />
do maxTries <- ask -- Get the maxTries from Reader Env<br />
gs <- lift getLine -- get guess from user<br />
let g = read gs -- convert to number<br />
tell $ [g] -- Log guess to Writer<br />
modify (+1) -- increment number of guesses in State<br />
tries <- get -- Get current number of guess from State<br />
case (compare g answer, compare tries maxTries) of<br />
(EQ, _) -> do lift $ putStrLn "Got it!"<br />
(LT,EQ) -> do lift $ putStrLn "Too low"<br />
lift $ putStrLn "Game over!"<br />
(GT,EQ) -> do lift $ putStrLn "Too high"<br />
lift $ putStrLn "Game over!"<br />
(LT, _) -> do lift $ putStrLn "Too low"<br />
guessSession answer<br />
(GT, _) -> do lift $ putStrLn "Too high"<br />
guessSession answer<br />
</haskell><br />
<br />
[[Category:Code]]<br />
[[Category:Monad]]</div>Psyburhttps://wiki.haskell.org/index.php?title=Simple_RWST_use&diff=62280Simple RWST use2018-01-09T19:46:08Z<p>Psybur: </p>
<hr />
<div>RWST on IO example.<br\><br />
Guess the number between 1 and 10 within a certain number of tries.<br\><br />
Guesses are entered via stdin.<br />
<br />
Reader: Env is max tries.<br\><br />
Writer: Guesses are logged to a String.<br\><br />
State: Number of guesses in session.<br\><br />
IO: Get next guess from stdin.<br\><br />
<br />
<haskell><br />
import System.Random<br />
import Control.Monad.RWS<br />
<br />
main = do answer <- getStdRandom (randomR (1,10)) -- think of a number<br />
let maxTries = 5<br />
putStrLn "I'm thinking of a number between 1 and 10, can you guess it?"<br />
putStrLn $ "You've got " ++ show maxTries ++ " tries!"<br />
(guesses,log) <- execRWST (guessSession answer) maxTries 0<br />
putStrLn $ "Finished in " ++ (show guesses) ++ " tries."<br />
putStrLn $ "Guesses: " ++ show log<br />
<br />
guessSession :: Int -> RWST Int [Int] Int IO ()<br />
guessSession answer =<br />
do maxTries <- ask -- Get the maxTries from Reader Env<br />
gs <- lift getLine -- get guess from user<br />
let g = read gs -- convert to number<br />
tell $ [g] -- Log guess to Writer<br />
modify (+1) -- increment number of guesses in State<br />
tries <- get -- Get current number of guess from State<br />
case (compare g answer, compare tries maxTries) of<br />
(EQ, _) -> do lift $ putStrLn "Got it!"<br />
(LT,EQ) -> do lift $ putStrLn "Too low"<br />
lift $ putStrLn "Game over!"<br />
(GT,EQ) -> do lift $ putStrLn "Too high"<br />
lift $ putStrLn "Game over!"<br />
(LT, _) -> do lift $ putStrLn "Too low"<br />
guessSession answer<br />
(GT, _) -> do lift $ putStrLn "Too high"<br />
guessSession answer<br />
</haskell><br />
<br />
[[Category:Code]]<br />
[[Category:Monad]]</div>Psyburhttps://wiki.haskell.org/index.php?title=Simple_RWST_use&diff=62279Simple RWST use2018-01-09T19:43:46Z<p>Psybur: Created page with "RWST on IO example. Guess the number between 1 and 10 within a certain number of tries. Guesses are entered via stdin. Reader: Env is max tries Writer: Guesses are logged to ..."</p>
<hr />
<div>RWST on IO example.<br />
Guess the number between 1 and 10 within a certain number of tries.<br />
Guesses are entered via stdin.<br />
<br />
Reader: Env is max tries<br />
Writer: Guesses are logged to a String.<br />
State: Number of guesses in session.<br />
IO: Get next guess from stdin<br />
<br />
<haskell><br />
import System.Random<br />
import Control.Monad.RWS<br />
<br />
main = do answer <- getStdRandom (randomR (1,10)) -- think of a number<br />
let maxTries = 5<br />
putStrLn "I'm thinking of a number between 1 and 10, can you guess it?"<br />
putStrLn $ "You've got " ++ show maxTries ++ " tries!"<br />
(guesses,log) <- execRWST (guessSession answer) maxTries 0<br />
putStrLn $ "Finished in " ++ (show guesses) ++ " tries."<br />
putStrLn $ "Guesses: " ++ show log<br />
<br />
guessSession :: Int -> RWST Int [Int] Int IO ()<br />
guessSession answer =<br />
do maxTries <- ask -- Get the maxTries from Reader Env<br />
gs <- lift getLine -- get guess from user<br />
let g = read gs -- convert to number<br />
tell $ [g] -- Log guess to Writer<br />
modify (+1) -- increment number of guesses in State<br />
tries <- get -- Get current number of guess from State<br />
case (compare g answer, compare tries maxTries) of<br />
(EQ, _) -> do lift $ putStrLn "Got it!"<br />
(LT,EQ) -> do lift $ putStrLn "Too low"<br />
lift $ putStrLn "Game over!"<br />
(GT,EQ) -> do lift $ putStrLn "Too high"<br />
lift $ putStrLn "Game over!"<br />
(LT, _) -> do lift $ putStrLn "Too low"<br />
guessSession answer<br />
(GT, _) -> do lift $ putStrLn "Too high"<br />
guessSession answer<br />
</haskell></div>Psyburhttps://wiki.haskell.org/index.php?title=99_questions/Solutions/2&diff=6218299 questions/Solutions/22017-10-25T14:30:46Z<p>Psybur: </p>
<hr />
<div>(*) Find the last but one element of a list.<br />
<br />
<haskell><br />
myButLast :: [a] -> a<br />
myButLast = last . init<br />
<br />
myButLast' x = reverse x !! 1<br />
<br />
myButLast'' [x,_] = x<br />
myButLast'' (_:xs) = myButLast'' xs<br />
<br />
myButLast''' (x:(_:[])) = x<br />
myButLast''' (_:xs) = myButLast''' xs<br />
<br />
myButLast'''' = head . tail . reverse<br />
<br />
lastbut1 :: Foldable f => f a -> a<br />
lastbut1 = fst . foldl (\(a,b) x -> (b,x)) (err1,err2)<br />
where<br />
err1 = error "lastbut1: Empty list"<br />
err2 = error "lastbut1: Singleton"<br />
<br />
lastbut1safe :: Foldable f => f a -> Maybe a<br />
lastbut1safe = fst . foldl (\(a,b) x -> (b,Just x)) (Nothing,Nothing)<br />
<br />
myButLast''''' [] = error "Empty list"<br />
myButLast''''' [x] = error "Too few elements"<br />
myButLast''''' (x:xs) = <br />
if length xs == 1 then x<br />
else myButLast''''' xs<br />
<br />
myButLast'''''' = head . reverse . init<br />
</haskell><br />
<br />
<br />
[[Category:Programming exercise spoilers]]</div>Psyburhttps://wiki.haskell.org/index.php?title=Talk:Tying_the_Knot&diff=62166Talk:Tying the Knot2017-10-12T14:54:46Z<p>Psybur: </p>
<hr />
<div>There's a conceptually much simpler way build a circular structure, though it has a substantial performance overhead (n^2) the first time you run through the nodes:<br />
<br />
mkDLList list = head result where<br />
(result, n) = (zipWith mknode list [0..], length list)<br />
mknode x i = DLList (result !! ((i - 1) `mod` n) ) x (result !! (i + 1 `mod` n) )<br />
<br />
Since we already have the result - the list of all the relevant nodes - we just simply point to the items at the right points on the list. When we do it this way, it's obvious what is going on from just a basic understanding of laziness, then we see a huge waste of operations in the repeat list traversing, and look for some way to make it O(n). The trick, of course, being tying the knot.<br />
<br />
With a slight tweak, this also serves as a simple method for defining arbitrary graphs, which is best given a different sort of optimization.<br />
<br />
[[User:WarDaft|WarDaft]] 17:25, 11 April 2012 (UTC)<br />
<br />
== takeF and takeR in the DList example do not compile for me ==<br />
<br />
I had to modify them as so:<br />
<br />
<haskell><br />
takeF :: Integer -> DList a -> [a]<br />
takeF 0 _ = []<br />
takeF n (DLNode _ x next) = x : (takeF (n-1) next)<br />
<br />
takeR :: Show a => Integer -> DList a -> [a]<br />
takeR 0 _ = []<br />
takeR n (DLNode prev x _) = x : (takeR (n-1) prev)<br />
</haskell><br />
<br />
[[User:Psybur|Psybur]] 15:10, 12 October 2017 (UTC)</div>Psyburhttps://wiki.haskell.org/index.php?title=Talk:Tying_the_Knot&diff=62165Talk:Tying the Knot2017-10-12T14:53:32Z<p>Psybur: /* takeF and takeR in the DList example do not compile for me */ new section</p>
<hr />
<div>There's a conceptually much simpler way build a circular structure, though it has a substantial performance overhead (n^2) the first time you run through the nodes:<br />
<br />
mkDLList list = head result where<br />
(result, n) = (zipWith mknode list [0..], length list)<br />
mknode x i = DLList (result !! ((i - 1) `mod` n) ) x (result !! (i + 1 `mod` n) )<br />
<br />
Since we already have the result - the list of all the relevant nodes - we just simply point to the items at the right points on the list. When we do it this way, it's obvious what is going on from just a basic understanding of laziness, then we see a huge waste of operations in the repeat list traversing, and look for some way to make it O(n). The trick, of course, being tying the knot.<br />
<br />
With a slight tweak, this also serves as a simple method for defining arbitrary graphs, which is best given a different sort of optimization.<br />
<br />
[[User:WarDaft|WarDaft]] 17:25, 11 April 2012 (UTC)<br />
<br />
== takeF and takeR in the DList example do not compile for me ==<br />
<br />
I had to modify them as so:<br />
<br />
<haskell><br />
takeF :: Integer -> DList a -> [a]<br />
takeF 0 _ = []<br />
takeF n (DLNode _ x next) = x : (takeF (n-1) next)<br />
<br />
takeR :: Show a => Integer -> DList a -> [a]<br />
takeR 0 _ = []<br />
takeR n (DLNode prev x _) = x : (takeR (n-1) prev)<br />
</haskell></div>Psybur