This is a summary of the "Learn You A Haskell" online book under http://learnyouahaskell.com/chapters.
- Haskell is a functional programming language.
=Navigating= | |
visit('/projects') | |
visit(post_comments_path(post)) | |
=Clicking links and buttons= | |
click_link('id-of-link') | |
click_link('Link Text') | |
click_button('Save') | |
click('Link Text') # Click either a link or a button | |
click('Button Value') |
This is a summary of the "Learn You A Haskell" online book under http://learnyouahaskell.com/chapters.
# lib/decent_exposure/draper_strong_parameters_strategy.rb: | |
class DraperStrongParametersStrategy < DecentExposure::StrongParametersStrategy | |
def resource | |
super.decorate | |
end | |
end | |
# app/controllers/articles.rb |
/// A type equality guarantee is capable of safely casting one value to a | |
/// different type. It can only be created when `S` and `T` are statically known | |
/// to be equal. | |
struct TypeEqualityGuarantee<S, T> { | |
private init() {} | |
/// Safely cast a value to the other type. | |
func cast(_ value: T) -> S { | |
return value as! S | |
} |
import scala.language.higherKinds | |
/* | |
Mainline Profunctor Heirarchy for Optics: https://r6research.livejournal.com/27476.html | |
Profunctor Optics: The Categorical Approach - Bartosz Milewski: https://www.youtube.com/watch?v=l1FCXUi6Vlw | |
*/ | |
object ProfunctorOpticsSimpleImpl { | |
trait Functor[F[_]] { | |
def map[A, B](x: F[A])(f: A => B): F[B] |
Monads and delimited control are very closely related, so it isn’t too hard to understand them in terms of one another. From a monadic point of view, the big idea is that if you have the computation m >>= f
, then f
is m
’s continuation. It’s the function that is called with m
’s result to continue execution after m
returns.
If you have a long chain of binds, the continuation is just the composition of all of them. So, for example, if you have
m >>= f >>= g >>= h
then the continuation of m
is f >=> g >=> h
. Likewise, the continuation of m >>= f
is g >=> h
.
import scala.annotation.tailrec | |
import Graph._ | |
case class Graph[N, A, B](repr: Map[N, Context[N, A, B]]) { | |
def &(c: Context[N, A, B]): Graph[N, A, B] = { | |
val Context(p, v, _, s) = c | |
if (repr contains v) | |
throw new IllegalArgumentException("node already exists") |
Jan Nasiadka from scalac contacted me to get some feedback about our usage of ZIO. My answers below, since they can benefit the community more broadly.
Context: we use ZIO in the context of https://rudder.io, a scala application that is 11 years old - far from a greenfield application with ZIO as base architectural choice. We used ZIO as a better framework to cleanly manage errors, porting piece of existing code to it. We are part of ZIO community since 2018 (since ZIO inception, when it was not yet ZIO but a part of scalaz, and when there was only a bifunctor, no context in it). Given our usage, we use ZIO in a specific way: we have tons of entry points and evaluation of ZIO effects, not one main entry point in the "main" method of the app. For correctness, that forced us to call a lot of blocking effects (you never know what a java lib is doing), and so we stressed the thread pool ergonomics, and helped make that part better (and some part
import qualified Data.Set as S | |
import Data.Set (Set) | |
import Data.Char (isLower) | |
import Data.Ord (comparing, Down (Down)) | |
import Data.List (sortBy, subsequences, minimumBy, maximumBy) | |
import Control.Monad.Trans.Writer.CPS | |
import Data.Monoid | |
import Data.Foldable (traverse_) | |
wordFilter :: String -> Bool |
Think of all the arguments you've heard as to why static typing is desirable — every single one of those arguments applies equally well to using types to represent error conditions.
An odd thing I’ve observed about the Scala community is how many of its members believe that a) a language with a sophisticated static type system is very valuable; and b) that using types for error handling is basically a waste of time. If static types are useful—and if you like Scala, presumably you think they are—then using them to represent error conditions is also useful.
Here's a little secret of functional programming: errors aren't some special thing that operate under a different set of rules to everything else. Yes, there are a set of common patterns we group under the loose heading "error handling", but fundamentally we're just dealing with more values. Values that can have types associated with them. There's absolutely no reason why the benefits of static ty