View gist:f64393b9349592b6f1c1
# 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 |
View class_currying.rb
# 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. | |
# |
View gist:12cb2e444dd2024d9836
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" |
View multi_send.rb
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) |
View curry.rb
# 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 } } |
View which_bar.rb
WhichBar = | |
Filter::Lift | |
| Filter::Singular.new( | |
attribute: :open, | |
value: true | |
) | |
| Filter::Collection.new( | |
attribute: :people, | |
aggregator: { | |
klass: :compare, |
View lol.hs
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 |
View freeeeee.hs
-- 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 |
View dpll.hs
{- | |
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}) |
View rose.hs
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 |
OlderNewer