Skip to content

Instantly share code, notes, and snippets.

View ChrisPenner's full-sized avatar
:bowtie:
Happily Hacking

Chris Penner ChrisPenner

:bowtie:
Happily Hacking
View GitHub Profile
@ChrisPenner
ChrisPenner / copy.sh
Created April 5, 2020 18:15
Copy/Pasta
#!/bin/bash
# Use at your own risk :P
FOLDER="/tmp/copy-pasta"
if [ $# -lt 1 ]; then
cat << EOF
usage: copy <files>
EOF
exit 1
fi
{-# LANGUAGE OverloadedStrings #-}
module TextSpan where
import Control.Lens
import qualified Data.Text as T
import Text.RawString.QQ (r)
import qualified Data.List as List
type Line = Int
type Col = Int
import Control.Lens
import Data.Typeable
import Data.Dynamic
dynamicLens :: Typeable a => (Lens' s a) -> Lens' s Dynamic
dynamicLens l = lens getter setter
where
getter s = toDyn $ view l s
setter s b =
case fromDynamic b of
@ChrisPenner
ChrisPenner / kleisli-endo.md
Last active October 22, 2019 03:44
Kleisli Endo

After listening to the latest Magic Read-along episode "You should watch this" (which you should go listen to now) I got caught up thinking about Brian's idea of an Endomorphism version of Kleisli composition for use with Redux, it's actually a very similar model to what I'm using in my event framework for event listeners so I figured I'd try to formalize the pattern and recognize some of the concepts involved. IIRC Brian described the idea of a Redux-reducer, which is usually of type s -> Action -> s, it takes a state and an action and returns a new state. He then re-arranged the arguments to Action -> s -> s. He then recognized this as Action -> Endo s (an Endo-morphism is just any function from one type to itself: a -> a). He would take his list of reducers and partially apply them with the Action, yielding a list of type Endo s where s

@ChrisPenner
ChrisPenner / OpticsTraverse.hs
Created October 4, 2019 16:07
Optics traversals
You can use *most* optics as though they're a custom `traverse`
>>> (each . _Right) print (Left 1, Right 2, Left 3)
2
-- We can ignore the new structure it returns
(Left 1,Right (),Left 3)
It works on other types of effects too!
Here we use lists as a non-determinism effect to get all possible combos!
@ChrisPenner
ChrisPenner / Lib.hs
Created October 1, 2019 04:07
Cofree animation
module Lib where
import Control.Comonad.Cofree
import Control.Monad.Reader
import Control.Concurrent
drawBar :: Float -> IO ()
drawBar n = putStrLn (replicate (ceiling n) '#')
type Animation = Cofree (Reader Float) Float
@ChrisPenner
ChrisPenner / InfixHoles.hs
Created September 18, 2019 22:12
Infix Typed Holes
*Infix* typed holes!
>>> "suggest" `_` "concat" :: String
<interactive>:1:11: error:
• Found hole: _ :: [Char] -> [Char] -> String
Valid hole fits include
showString :: String -> ShowS
(++) :: forall a. [a] -> [a] -> [a]
showList :: forall a. Show a => [a] -> ShowS
@ChrisPenner
ChrisPenner / ChooseIndex.hs
Created September 14, 2019 18:01
Gain extra context in your lens chain by passing values as an index!
Sometimes when diving deep with optics you need to reference something earlier in your path after you dive deeper. Just stash it in your index!
Let's say we want to know which pets belong to which owner, we've got the data paired up like this:
pets :: [(String, [String])]
pets =
[ ("Steven", ["Spot", "Mittens"])
, ("Kaylee", ["Pepper", "Sparky"])
]
@ChrisPenner
ChrisPenner / LensyBinarySearch.hs
Created August 27, 2019 05:36
Binary tree search using lenses
-- Define a simple binary tree
data BT a
= BT { _leftTree :: BT a
, _val :: a
, _rightTree :: BT a
}
| Leaf
deriving (Show, Eq, Functor, Foldable, Traversable)
-- Generate traversals for the (partial) fields
makeLenses ''BT
@ChrisPenner
ChrisPenner / FindIslands.hs
Last active August 23, 2019 16:09
A quick experiment using union-find to determine which pieces of 'land' in a grid are connected. Could ostensibly be used with any equivalence/grouping predicate.
{-# LANGUAGE ScopedTypeVariables #-}
module Lib where
import Data.UnionFind.IO
import Control.Monad
import Control.Applicative
import Data.Foldable
import Data.Maybe
import qualified Data.Map as M
import qualified Data.Set as S