Skip to content

Instantly share code, notes, and snippets.

@parsonsmatt
parsonsmatt / gist:f64393b9349592b6f1c1
Last active August 28, 2020 17:36
class composition in ruby
# In Haskell, you write a function like this:
# f :: a -> b
# which reads as "f is a function from type a to b"
#
# Function composition allows you to chain functions together,
# building more powerful and complex composite functions from
# simpler component functions.
#
# OOP does not have a similar mechanism. Composition in OOP seems
# to mostly be limited to aggregation and delegation, neither of
@parsonsmatt
parsonsmatt / class_currying.rb
Last active August 29, 2015 14:23
ruby class currying
# gem install 'beethoven'
require 'beethoven'
# Beethoven enables class composition. Unfortunately, the mechanism
# seems to be somewhat limited: each class only takes a single argument
# in the `new` method.
#
# While composing classes in this manner can be powerful, the true
# power is lost without the ability to "curry" this class composition.
#
module Auth where
main :: IO ()
main = putStrLn $ unlines $
[ "pretend website"
, "Logged in as regular user, trying to see my profile"
, if authorize regUser Read regUser
then profile regUser
else "forbidden"
, "Logged in as admin, trying to delete post"
class Object
def send_array(*messages)
messages.reduce(self) { |obj, message| obj.send(*message) }
end
def send_hash(**messages)
send_array(messages.map { |k, v| [k, *v] })
end
def multi_send(*messages)
@parsonsmatt
parsonsmatt / curry.rb
Created July 23, 2015 22:25
when currying is useful
# Currying: What, How, Why
# Currying is a way to change the arity of functions.
add = -> x, y { x + y }
# Any function that takes multiple arguments can be expressed as a function
# that takes a single argument, and returns a function taking a single
# argument, etc. until eventually all arguments are given and a value is
# returned.
add = -> x { -> y { x + y } }
@parsonsmatt
parsonsmatt / which_bar.rb
Last active August 29, 2015 14:25
muh filters
WhichBar =
Filter::Lift
| Filter::Singular.new(
attribute: :open,
value: true
)
| Filter::Collection.new(
attribute: :people,
aggregator: {
klass: :compare,
allDifferent :: Ord d => [ID] -> Constraints d
allDifferent ids = do
domains <- forM ids (use . domainAt)
let unified = mconcat domains
newDomains = map (\d -> d \\ (unified \\ d)) domains
zipWithM_ updateVariable ids newDomains
@parsonsmatt
parsonsmatt / freeeeee.hs
Last active November 11, 2015 02:23
to free or not to free
-- so I can either have a convention on returning a bare bool value
-- out of this strangeness.
data AndF k = forall f. (AndF :<: f) => And (Free f Bool) (Free f Bool) (Bool -> k)
testProgram :: (AndF :<: f) => Free f Bool
testProgram = do
asdf <- true .&& false
hmmm <- false .&& true
wat <- pure asdf .&& pure hmmm
{-
DPLL from the textbook:
function DPLL(clauses, symbols, model ) returns true or false
if every clause in clauses is true in model then return true
if some clause in clauses is false in model then return false
P , value ← FIND-PURE-SYMBOL (symbols, clauses, model )
if P is non-null then return DPLL(clauses, symbols – P , model ∪ {P =value})
P, value ← FIND-UNIT-CLAUSE (clauses, model)
if P is non-null then return DPLL(clauses, symbols – P , model ∪ {P =value})
@parsonsmatt
parsonsmatt / rose.hs
Last active November 27, 2015 03:05
module Rose where
import Data.List (findIndex)
data Tree a = Node { value :: a, getSubForest :: [Tree a] } deriving Show
insertPath :: (Eq a ) => [a] -> Tree a -> Tree a
insertPath [] tree = tree
insertPath (x:xs) (Tree a subForest) = Tree a modifiedSubForest
where