Skip to content

Instantly share code, notes, and snippets.

View ramirez7's full-sized avatar
💗
Grey hairs are visible / I'm kinda of miserable, too

Armando Ramirez ramirez7

💗
Grey hairs are visible / I'm kinda of miserable, too
View GitHub Profile

I often see effects called "fancy," but in 2024 I fail to see how that is the case. If anything, their types are more clear than mtl in 2024.

I've been using extensible effects (via cleff [1]) in my gamedev code since 2021 (starting with Ludum Dare 49). I originally used mtl, but it was almost immediately a pain. I saw cleff and switched to it within a day (for both library code + my previous game). I can confidently say I'll never use mtl again if I have any choice. It's archaic and brings no benefit besides somehow being considered less fancy.

I say "somehow" because I don't really understand why mtl is considered less fancy than cleff. Maybe it's because it's fancier to implement? But the whole point of Haskell is that you shouldn't need to care about the implementation if

{-# LANGUAGE AllowAmbiguousTypes #-}
import Data.Coerce
import Data.Foldable
foldMapVia
:: forall b f r a
. Coercible r b
=> Monoid b
=> Foldable f
-- Similar to this old gist https://gist.github.com/ramirez7/11167d5f1c2a1153c3fb20643f4cb2d4
--
-- Scala is a bit more general though thanks to its path-dependent types
module SetBy
( SetBy
) where
import Data.Map (Map)
import qualified Data.Map as Map
import GHC.TypeLits
@ramirez7
ramirez7 / spew-error.hs
Created May 6, 2024 19:36
Make an arbitrarily large Haskell error message (and make your computer very warm)
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -freduction-depth-0 #-}
import GHC.TypeLits
data N = Z | S N
@ramirez7
ramirez7 / time-ghci
Last active March 13, 2024 14:57
Get the _real_ time of stuff in ghci
:{
let ghciTime cmd = do
let mkVar n u = "ghciTime_" ++ n ++ "_" ++ show (Data.Unique.hashUnique u)
startVar <- mkVar "start" <$> Data.Unique.newUnique
resVar <- mkVar "res" <$> Data.Unique.newUnique
endVar <- mkVar "end" <$> Data.Unique.newUnique
pure $ unlines
[ startVar ++ " <- Data.Time.getCurrentTime"
, resVar ++ "<- " ++ cmd
, endVar ++ " <- Data.Time.getCurrentTime"
@ramirez7
ramirez7 / hlist-gadt.hs
Created February 20, 2024 22:24
HList via GADTs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
module HList.GADT where
import Data.Kind
data HList (ts :: [Type]) where
HNil :: HList '[]
HCons :: forall t ts. t -> HList ts -> HList (t ': ts)
@ramirez7
ramirez7 / gadt-X.hs
Last active February 5, 2024 21:19
G X XX
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE LambdaCase #-}
import Data.Kind
data I a
data X a
data XX
@ramirez7
ramirez7 / th-ghci
Last active January 11, 2024 19:09
ghci command to run top-level TH. Thanks /u/affinehyperplane for the trick! https://www.reddit.com/r/haskell/comments/18vkivp/comment/kh9byjd/?utm_source=reddit&utm_medium=web2x&context=3
:{
let doTH code = do
u <- Data.Unique.newUnique
let decls = "ghciTH_" ++ show (Data.Unique.hashUnique u)
pure $ unlines
[ unwords ["let", decls, "=", code]
, "() = ();" ++ decls
]
:}
concat(zipWith replicate [1,2,1,0] "cold")
-- Desugar string literal to [Char]
concat(zipWith replicate [1,2,1,0] ['c', 'o', 'l', 'd'])
-- https://hackage.haskell.org/package/base-4.19.0.0/docs/src/GHC.List.html#zipWith
-- Rewritten to not use the "go" helper, zipWith is:
-- zipWith f [] _ = []
-- zipWith f _ [] = []
-- zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
@ramirez7
ramirez7 / col.md
Created November 15, 2023 20:26 — forked from vurtun/col.md

screen0 screen1