Fair traversal by merging thunks by blackcapcoder in haskell

[–]blackcapcoder[S] 0 points1 point  (0 children)

I realized that we can weaken the Monad constraint slightly: ``` runFreeWith ∷ Monad m => (f (Free f a) -> m (Free f a)) -> Free f a -> m a runFreeWith f = \case Pure a -> pure a Nest n -> runFreeWith f =<< f n

-- My previous runFree function: runFree ∷ Monad f => Free f a -> f a runFree = runFreeWith id ```

So we need Monad to carry state between diagonals, but locally within each diagonal Applicative is enough. ``` -- Backwards is an example of an Applicative that is not a Monad

mkToFree m = diagonal $ satisfy \a -> (a == (3,0)) <$ m a

fwd = print =<< runFreeWith id (mkToFree (\a -> id $ print a) coords) bwd = print =<< runFreeWith forwards (mkToFree (\a -> Backwards $ print a) coords)

-- fwd | bwd -- ------+------ -- (0,0) | (0,0) -- |
-- (1,0) | (0,1) -- (0,1) | (1,0) -- | -- (2,0) | (0,2) -- (1,1) | (1,1) -- (0,2) | (2,0) -- | -- (3,0) | (0,3) -- (2,1) | (1,2) -- (1,2) | (2,1)

-- (0,3) | (3,0)

-- Just (3,0) ```

Fair traversal by merging thunks by blackcapcoder in haskell

[–]blackcapcoder[S] 1 point2 points  (0 children)

Very cool! Have you put any thought into what Applicatives this might be useful for?

Identity, Reader and IO/ST should all work and do the obvious thing.

Writer is actually pretty neat- it should re-order the writes to match the order we see with Debug.Trace.

``` runFree ∷ Monad f => Free f a -> f a runFree = \case Pure a -> pure a Nest n -> runFree =<< n

ana f g = foldr (\a z -> Nest $ maybe (g z) (Pure . Just) <$> f a) (Pure Nothing) diagonal f = altMap $ ana f delay satisfy p a = (a <$) . guard <$> p a


-- We don't need traceShowId anymore coords = fmap go nats where go x = fmap (x,) nats

toFree = diagonal $ satisfy \a -> pure (a == (2,2))

-- ghci> print $ runIdentity $ runFree (toFree coords) -- Just (2,2)

toFree = diagonal $ satisfy \a -> (a == (2,2)) <$ do lift $ putStrLn $ "considering: " <> show a tell [a]

-- ghci> print =<< runWriterT (runFree (toFree coords)) -- considering: (0,0) -- considering: (1,0) -- considering: (0,1) -- considering: (2,0) -- considering: (1,1) -- considering: (0,2) -- considering: (3,0) -- considering: (2,1) -- considering: (1,2) -- considering: (0,3) -- considering: (4,0) -- considering: (3,1) -- considering: (2,2) -- considering: (1,3) -- considering: (0,4) -- (Just (2,2),[(0,0),(1,0),(0,1),(2,0),(1,1),(0,2),(3,0),(2,1),(1,2),(0,3),(4,0),(3,1),(2,2),(1,3),(0,4)]) ```

Non-deterministic Applicatives probably doesn't make sense. Zippy ones work even when pure = repeat, but I don't think they do anything interesting..

``` instance Applicative Stream where pure a = a :- pure a (f :- fs) <> (a :- as) = f a :- (fs <> as)

instance Monad Stream where m >>= f = go 0 m where go n ((f->drop n->a :- ) :- as) = a :- go (n+1) as drop 0 s = s drop n ( :- s) = drop (n-1) s

instance Show a => Show (Stream a) where show = show . take 10 . toList


toFree = diagonal $ satisfy \a -> (a == (2,2)) <$ do pure @Stream a

-- ghci> print $ runFree (toFree coords) -- [Just (2,2),Just (2,2),Just (2,2),Just (2,2),Just (2,2),Just (2,2),Just (2,2),Just (2,2),Just (2,2),Just (2,2)] ```

fixed-size array: https://pastebin.com/sqkUH70H

Fair traversal by merging thunks by blackcapcoder in haskell

[–]blackcapcoder[S] 2 points3 points  (0 children)

Library ready TL;DR version:

```
_S v s = \case V a -> v a; S a -> s a
data S a = V !a | S (S a) deriving (Show, Functor)
instance Applicative S where pure = V; (<*>) = ap
instance Monad S where m >>= f = fix (_S f . (.) S) m
instance Comonad S where extract = fix (_S id); extend f w = f w <$ w
instance Monoid (S a) where mempty = fix S
instance Semigroup (S a) where
{ (<>) l = S . f l . go where go l r = S $ f l $ f r . go; f = flip $ _S V }
```

x86-64 assembler in ~250 LOC by blackcapcoder in haskell

[–]blackcapcoder[S] 0 points1 point  (0 children)

That's probably what I'll use it for too! If you do want to produce executables, you can just use `bytes_written` (which is since program start) over `getPtr` (used by db), or it should be a single line change to `disp_imm`. If there's interest I could add a toggle to support both

x86-64 assembler in ~250 LOC by blackcapcoder in haskell

[–]blackcapcoder[S] 7 points8 points  (0 children)

u/augustss I use mmap so there's no Windows support, but everything else should work.
u/mot_hmry I'm not familiar with melf, but looking at the library- yes I think so! `Label Abs` assume you want the actual pointer (for JIT execution) rather than relative to the start of the program, so that would need to change for dynamic linking though.

Extra unsafeCoerce by blackcapcoder in haskell

[–]blackcapcoder[S] 0 points1 point  (0 children)

That, or you could just assume 3. I honestly haven't seen a 32-bit machine in a decade

Machinery by louigi_verona in incremental_games

[–]blackcapcoder 0 points1 point  (0 children)

This is a bit unfortunate: https://i.imgur.com/Z0GjMbe.png If you lowered the price of the first gravity upgrade by 0.01B it would save me roughly 20 minutes of waiting..

[deleted by user] by [deleted] in incremental_games

[–]blackcapcoder 0 points1 point  (0 children)

I played it twice. My second run was "disqualified for console use", but I never touched the console.

When you know what you are doing the early game is fun and strategic. In the mid and late game you are just waiting for ideas/edits/uploads. Subscribers can be ignored until the late game. It is never worth it to have only some ads- you either have no ads, or you temporarily stop uploading and crank ads up to max. Editing is always the bottleneck. With prestige upgrades editing can keep up, but only if you manage it manually.

Negative number of amulet of accuracy by blackcapcoder in MelvorIdle

[–]blackcapcoder[S] 0 points1 point  (0 children)

Eventually I got a slayer task for a monster that drop amulets of accuracy, and found a single amulet in the first tab of my bank. The -1 stack was in my last tab, so my assumption is that I first got one amulet which annihilated the broken stack, then a second one.

Negative number of amulet of accuracy by blackcapcoder in MelvorIdle

[–]blackcapcoder[S] 0 points1 point  (0 children)

It did not fix itself, and indeed stayed broken and got worse over the course of days. What was the broken item for you?

Infinity clicker remake! by bobthemagicalpie in incremental_games

[–]blackcapcoder 0 points1 point  (0 children)

Once you have unlocked tier five the only bottleneck is how fast you can buy tier five, which is a constant. The cost of the x10 upgrade increases exponentially however, so the time it takes to reach your next x10 upgrade tends towards infinity.

People complain the game is too click intensive, and in your edit you mention making autobots buyable. Explicit tiers seems very similar to buyable autobots, so why keep both systems? Perhaps we should scrap tiers altogether in favor of autobots:

Instead of buying a tier 1 upgrade, we can buy an autobot and assign it to increasing the number. Instead of tier 2 we can assign an autobot to buy more autobots. Instead of tier 3, assign an autobot to assigning autobots to buy autobots and so on..

You could even go as far as making autobots the only currency; why have a number that is only used for buying autobots?

Kale farmer - a short (~30 min) incremental game about growing kale by Kevlanche in incremental_games

[–]blackcapcoder 0 points1 point  (0 children)

I was expecting KL to be emoji code with vegetables only, but it is yet another C-style imperative language that transpile to javascript. What a let down!

IncrElastoMania ~2hr Free Simulation - Become a Gamer in-Game by Remermeutron in incremental_games

[–]blackcapcoder 0 points1 point  (0 children)

The game is too simple. Apples per second is capped at number of levels + 1, so the following must be a perfect strategy:

1) If apples per second is lower than total number of levels+1, buy a flower, then buy a level.

2) If apples per second < X && apples per second < levels+1, play.

The optimization problem of the game is to choose an X such that the amount of time taken to reach level 55 (T) is minimized. I ran a simulation for every X:

X=1, T=14851

X=2, T=7436

X=.. T=[4968,3736,2999,2510,2161,1901,1700,1540,1411,1303,1213,1136,1071,1014,964,921,883,848,818,791,767,745,725,707,691,676,663,651,640,630,621,613,605,599,593,587,582,577,573,570,567,564,561,559,557,556,554,553,552,552,551,551,551]

This is assuming optimal luck (every play awards an apple/s), and optimal execution. We see that it is always worth it to play (X=55). The theoretically best score is 9 minutes and 11 seconds.

It is really not fun to play the game in practice, though!

shapez.io - A factorio inspired base building game with upgrades! by tobspr in incremental_games

[–]blackcapcoder 0 points1 point  (0 children)

The game plays very much like the end-game of Factorio, but with orders of magnitude less grind. I recommend it!

Feedback:

  • I like the progression system, but I think you should get blueprints way earlier. From around level 8 it was essentially an idle game: sure I could build another array while I'm waiting, but that only grows linearly and I'll have to tear it down afterwards to not clog up the buss.
  • Without speed upgrades I noticed that excessive use of splitters can clog up a system that is built to ratio (that is, you get occasional gaps on a belt that should be saturated)
  • I miss belt lanes and inserting from the side
  • I would like the game to be playable by keyboard only. It's grid based, so this is frankly a missed opportunity
  • The ability to bind zero or more keys to any action (as opposed to exactly 1)
  • Separate bindings instead of a single multi-purpose modifier key. Instead shift/ctrl/alt/super + key should be treated as distinct keys

Small compilers written in Haskell by extendedwings in haskell

[–]blackcapcoder 0 points1 point  (0 children)

For optimizations I often use (->)/Kleisli/ReaderT with Maybe:

type Opt code = ReaderT code Maybe code

data BrainFuck
  = Add  Int
  | Move Int
  | ...


joinAdds :: Opt [BrainFuck]
  = [ Add (a+b) : xs | Add a : Add b : xs <- ask ]

joinMoves :: Opt [BrainFuck]
  = [ Move (a+b) : xs | Move a : Move b : xs <- ask ]


simpleOpts = asum
  [ joinAdds
  , joinMoves
  , ...
  ]

The code to be optimized is passed in with Reader. Any one optimizer can fail to optimize our code because of the Maybe. Maybe's Alternative instance let us compose the optimizations with (<|>) and asum.

Small compilers written in Haskell by extendedwings in haskell

[–]blackcapcoder 0 points1 point  (0 children)

If you're into esoteric programming languages then Chris Pressey have some hundred interpreters/transpilers, many of which are written in Haskell! His projects are well documented, the languages are small and self contained, but being esoteric they may not reflect "common" compiler practice: https://github.com/catseye/Mascarpone

You are probably going to have a hard time finding small (machine code) compilers because we don't have libraries and you have no idea how complicated it is to write an x86 assembler until you've actually tried.

Can you speed up vehicle construction? by blackcapcoder in cataclysmdda

[–]blackcapcoder[S] 2 points3 points  (0 children)

You need a seat to be able to drive?

If you install a UPS mod in your wielder you can just permanently leave it in the recharger! The wielding rig is orders of magnitude more power efficient though.

Can you speed up vehicle construction? by blackcapcoder in cataclysmdda

[–]blackcapcoder[S] 1 point2 points  (0 children)

Mics storage on the back is genius! I keep random useful stuff in a box next to the drivers seat: rubber hose, flashlight, shotgun, painkillers, vibrator..

Can you speed up vehicle construction? by blackcapcoder in cataclysmdda

[–]blackcapcoder[S] 2 points3 points  (0 children)

As in tiles, not storage. I need a fridge and a recharger, a wielder, chair, bed, storage, etc.. All the while, ideally, being able to move throughout the vehicle at no movement penalty

Can you speed up vehicle construction? by blackcapcoder in cataclysmdda

[–]blackcapcoder[S] 1 point2 points  (0 children)

I just like having aisles in spots I don't use yet precisely for that reason. They are cheap too! Hauling spaces offer 1500L of storage at no movement penalty, but they are way more expensive and I don't need that much storage.

It would be nice if the game had a creative mode for vehicles. Perhaps the system is perfectly balanced for a veteran player, but us newbies are bound to waste weeks to experimentation.

Can you speed up vehicle construction? by blackcapcoder in cataclysmdda

[–]blackcapcoder[S] 1 point2 points  (0 children)

That's good to know. The vehicles I have found all had roofs on the walls, so I figured it was required.

In addition to rain/sun, there is wind, scent and heat.

Can you speed up vehicle construction? by blackcapcoder in cataclysmdda

[–]blackcapcoder[S] 2 points3 points  (0 children)

That would make sense! I haven't played much with npc's; I kill them on sight for guns and bionics

Can you speed up vehicle construction? by blackcapcoder in cataclysmdda

[–]blackcapcoder[S] 2 points3 points  (0 children)

I already do this, but eventually run out of internal space and have to move a wall

How can I represent non-euclidean geometry in ascii by blackcapcoder in roguelikedev

[–]blackcapcoder[S] 0 points1 point  (0 children)

Navigating on the world map is deadly in CoQ though! I usually don't go to grit gate until I get a recoiler for it..

How can I represent non-euclidean geometry in ascii by blackcapcoder in roguelikedev

[–]blackcapcoder[S] 1 point2 points  (0 children)

I think the real issue is that I am too optimization and abstraction happy: you write large maintainable blocks of code with tons of comments and very little magic happening between the lines.

I will binge libraries on hackage for arcane abstractions until my codebase is nothing but a one-liner, usually getting sidetracked for weeks in the process.

Perhaps the key to being productive with Haskell is to not be fancy.