Logs: liberachat/#haskell
| 2021-08-06 23:17:12 | <dsal> | Yeah, I didn't even think about doing it that way. :) |
| 2021-08-06 23:17:34 | <euouae> | What do you think about 'CurrentState'? It's supposed to keep track of what happpend in the last move, which helps i.e. with the next user message |
| 2021-08-06 23:17:43 | <_73> | the way you represent the state of the game and update it with `update :: Game -> Char -> Game` makes sense to me. You cannot just modify some global state like in regular languages, you have to pass an old state and return a new state and that is what you did. |
| 2021-08-06 23:18:29 | <dsal> | euouae: CurrentState seems to conflate total game state and previous move state. |
| 2021-08-06 23:18:37 | → | futty joins (~futty@c83-252-75-55.bredband.tele2.se) |
| 2021-08-06 23:18:50 | <dsal> | but yeah, as _73 says, that part looks right. |
| 2021-08-06 23:19:15 | <euouae> | How do you keep it in a loop until the game is over? |
| 2021-08-06 23:19:17 | → | rlp10 joins (~rlp10@cpc77289-basf12-2-0-cust607.12-3.cable.virginm.net) |
| 2021-08-06 23:19:35 | <dsal> | I think the confusion is mixing all that state up. You can decide whether a particular guess is good or bad by just checking to see if the char you just picked up is in the list. |
| 2021-08-06 23:20:05 | <dsal> | `until (gameOver st) $ repl st` |
| 2021-08-06 23:20:23 | <euouae> | Yeah, I see what you mean. Minimal state is good for this problem but I was trying to engineer it |
| 2021-08-06 23:20:28 | <rlp10> | How do I create a lazy list (from which I can 'take') when I already have the first item and a function (call it 'nextItem') which takes the previous item in the list and gives the next one? |
| 2021-08-06 23:20:41 | <dsal> | :t iterate -- rlp10 |
| 2021-08-06 23:20:42 | <lambdabot> | (a -> a) -> a -> [a] |
| 2021-08-06 23:20:52 | <rlp10> | dsal: Thank you! |
| 2021-08-06 23:20:54 | → | kor1 joins (~kor1@user/kor1) |
| 2021-08-06 23:21:07 | ← | kor1 parts (~kor1@user/kor1) () |
| 2021-08-06 23:22:00 | <euouae> | wait how does until work |
| 2021-08-06 23:22:01 | <euouae> | I'm confused |
| 2021-08-06 23:22:12 | × | jgeerds quits (~jgeerds@55d45555.access.ecotel.net) (Ping timeout: 245 seconds) |
| 2021-08-06 23:22:21 | <dsal> | :t until |
| 2021-08-06 23:22:22 | <lambdabot> | (a -> Bool) -> (a -> a) -> a -> a |
| 2021-08-06 23:22:26 | <euouae> | aah nice. I see |
| 2021-08-06 23:22:39 | <euouae> | Good ol recursion saves the day |
| 2021-08-06 23:22:50 | <dsal> | @hoogle until |
| 2021-08-06 23:22:50 | <lambdabot> | Prelude until :: (a -> Bool) -> (a -> a) -> a -> a |
| 2021-08-06 23:22:50 | <lambdabot> | GHC.Base until :: (a -> Bool) -> (a -> a) -> a -> a |
| 2021-08-06 23:22:50 | <lambdabot> | Test.Hspec.Discover until :: () => (a -> Bool) -> (a -> a) -> a -> a |
| 2021-08-06 23:23:10 | <dsal> | I meant unless |
| 2021-08-06 23:23:18 | <dsal> | :t unless -- euouae |
| 2021-08-06 23:23:19 | <lambdabot> | Applicative f => Bool -> f () -> f () |
| 2021-08-06 23:23:24 | <euouae> | Oh, unless! Whoopos :D |
| 2021-08-06 23:23:27 | × | pschorf quits (~user@c-73-77-28-188.hsd1.tx.comcast.net) (Ping timeout: 245 seconds) |
| 2021-08-06 23:23:36 | × | eggplantade quits (~Eggplanta@108-201-191-115.lightspeed.sntcca.sbcglobal.net) (Remote host closed the connection) |
| 2021-08-06 23:23:42 | <euouae> | How do I use hedgehog for unit tests |
| 2021-08-06 23:23:44 | <dsal> | I actually am not familiar with until. That's strange. |
| 2021-08-06 23:23:53 | <dsal> | I've recently started using hedgehog. |
| 2021-08-06 23:24:26 | <euouae> | Seems complicated |
| 2021-08-06 23:24:35 | <euouae> | Not sure what generators are |
| 2021-08-06 23:24:39 | <dsal> | You just have to think of the property that's useful and build the generators around it. |
| 2021-08-06 23:24:42 | <dsal> | A generator creates input. |
| 2021-08-06 23:25:02 | <euouae> | So a generator for Int is, say, a random even Int? |
| 2021-08-06 23:25:07 | <dsal> | So like, you might have a phrase generator that creates a string "some test for junk" |
| 2021-08-06 23:25:58 | <dsal> | Then you could say something like "after all chars in this string are guessed, the game is over and I won" |
| 2021-08-06 23:26:48 | <euouae> | With until? yeah. I notice I have until and not unless |
| 2021-08-06 23:26:58 | <dsal> | I've mostly used QuickCheck so my brain still thinks of things that way. There are specific generator functions that give you different parts of range and stuff. |
| 2021-08-06 23:26:58 | <euouae> | At least in GHC.Base |
| 2021-08-06 23:27:07 | <dsal> | unless is Control.Monad |
| 2021-08-06 23:27:11 | <dsal> | I have no idea what until is. heh |
| 2021-08-06 23:27:24 | <euouae> | until is pure |
| 2021-08-06 23:27:40 | <euouae> | It's basically like iterate and take the first non-failure |
| 2021-08-06 23:27:49 | <dsal> | Yeah. I've not had a use for that before. |
| 2021-08-06 23:28:06 | <euouae> | Well, come to think of it, I can't use until since my functions need IO |
| 2021-08-06 23:28:13 | <euouae> | or I'd have to use >>= etc |
| 2021-08-06 23:28:43 | <dsal> | Forget I ever said until because that was confusing. I meant unless. |
| 2021-08-06 23:28:58 | <euouae> | Yaeh np I am on the same page now |
| 2021-08-06 23:29:13 | <dsal> | You have `repl :: Game -> IO Game` -- that needs to loop while the game is running, doesn't it? |
| 2021-08-06 23:29:58 | <euouae> | Yeah |
| 2021-08-06 23:29:59 | <dsal> | @hoogle untilM -- If you want to get fancy |
| 2021-08-06 23:30:00 | <lambdabot> | Prelude undefined :: forall (r :: RuntimeRep) . forall (a :: TYPE r) . HasCallStack => a |
| 2021-08-06 23:30:00 | <lambdabot> | Control.Exception.Base absentSumFieldError :: a |
| 2021-08-06 23:30:00 | <lambdabot> | Text.Printf errorShortFormat :: a |
| 2021-08-06 23:30:11 | <dsal> | that's... not what's supposed to happen |
| 2021-08-06 23:30:13 | <dsal> | @hoogle untilM |
| 2021-08-06 23:30:13 | <lambdabot> | Control.Monad.Loops untilM :: Monad m => m a -> m Bool -> m [a] |
| 2021-08-06 23:30:13 | <lambdabot> | Control.Monad.HT untilM :: Monad m => (a -> Bool) -> m a -> m a |
| 2021-08-06 23:30:13 | <lambdabot> | Control.Monad.Loops untilM' :: (Monad m, MonadPlus f) => m a -> m Bool -> m (f a) |
| 2021-08-06 23:30:21 | <dsal> | But you can just use unless for that. |
| 2021-08-06 23:30:21 | <euouae> | Lol |
| 2021-08-06 23:30:30 | <_73> | I made this modification to the repl function. It is not fancy like untilM: http://dpaste.com/695CCJ27U |
| 2021-08-06 23:30:52 | <euouae> | ooh modifications :D |
| 2021-08-06 23:30:55 | <dsal> | Yeah, that's basically `unless` |
| 2021-08-06 23:31:45 | <dsal> | This is the implementation of unless: `unless p s = if p then pure () else s` |
| 2021-08-06 23:31:51 | <euouae> | Yeah nice, thanks for that. Makes it clear |
| 2021-08-06 23:32:40 | <euouae> | That doesn't look like a loop, unless I call it inside repl |
| 2021-08-06 23:33:00 | <euouae> | Oh OK. So untilM is the fancy way of doing it, where you don't have to write it /inside/ repl |
| 2021-08-06 23:33:58 | <dsal> | `untilM` is a little extra fancy because the condition is monadic as well: `untilM :: Monad m => m a -> m Bool -> m [a]` |
| 2021-08-06 23:34:33 | <dsal> | But doing explicit recursion is fine. The nice thing about doing that condition explicitly is that you can return the final game state (or whatever you think that should return) |
| 2021-08-06 23:36:53 | <euouae> | _73's code? |
| 2021-08-06 23:37:09 | <euouae> | (is that... a boost lambda?) |
| 2021-08-06 23:37:38 | <dsal> | ? |
| 2021-08-06 23:37:45 | euouae | made a joke about the IRC user handle |
| 2021-08-06 23:37:50 | → | jmorris joins (uid433911@id-433911.stonehaven.irccloud.com) |
| 2021-08-06 23:38:22 | <euouae> | But the explicit recursion you spoke of, that's shown in the dpaste above. Or are you including unless? |
| 2021-08-06 23:39:01 | <dsal> | Well, they're both explicit recursion, but `unless` can only return (), with the dpaste above you can return whatever you want. |
| 2021-08-06 23:39:54 | <euouae> | Gotcha |
| 2021-08-06 23:41:52 | → | eggplantade joins (~Eggplanta@108-201-191-115.lightspeed.sntcca.sbcglobal.net) |
| 2021-08-06 23:44:16 | <euouae> | Nice, thanks you two :) |
| 2021-08-06 23:45:10 | <euouae> | One issue for me is that I'm too used to writing C++ to the point where I am trained to think in ways that optimize in time or space |
| 2021-08-06 23:45:44 | <euouae> | Can't strike a sensible balance |
| 2021-08-06 23:46:17 | <euouae> | It's a hangman game, have some mercy! |
| 2021-08-06 23:47:01 | × | rlp10 quits (~rlp10@cpc77289-basf12-2-0-cust607.12-3.cable.virginm.net) (Ping timeout: 246 seconds) |
| 2021-08-06 23:48:24 | × | MoC quits (~moc@user/moc) (Quit: Konversation terminated!) |
| 2021-08-06 23:51:33 | × | neightchan quits (~nate@108-233-125-227.lightspeed.sntcca.sbcglobal.net) (Remote host closed the connection) |
| 2021-08-06 23:51:53 | → | natechan joins (~nate@108-233-125-227.lightspeed.sntcca.sbcglobal.net) |
| 2021-08-06 23:54:54 | → | merijn joins (~merijn@83-160-49-249.ip.xs4all.nl) |
| 2021-08-07 00:00:10 | <_73> | euouae: explicit recursion is when you explicitly make a recursive function call. For example `sum [] = 0; sum (x:xs) = x + sum xs`. Contrast this with the equivalent definition which is still recursive but doesn't make an explicit call to itself: `sum xs = foldr (+) 0 xs`. |
| 2021-08-07 00:02:33 | <lechner> | Hi, being new to both Applicative and optparse-applicative, I cannot figure out how to integrate the "arguments" Parser for a potentially unlimited number of version strings into the poorly named "sample" Parser for the path of the configuration file. Any pointers would be appreciated. Thanks! https://dpaste.org/XgOU#L57,58 |
| 2021-08-07 00:04:06 | → | _73` joins (~user@pool-96-252-123-136.bstnma.fios.verizon.net) |
| 2021-08-07 00:05:30 | × | _73 quits (~user@pool-96-252-123-136.bstnma.fios.verizon.net) (Ping timeout: 240 seconds) |
All times are in UTC.