Skip to content

Instantly share code, notes, and snippets.

View matthughes's full-sized avatar

Matt Hughes matthughes

View GitHub Profile
@matthughes
matthughes / md_slack.rb
Last active March 6, 2024 21:21 — forked from h6y3/md_slack.rb
Obsidian Markdown to Slack
#!/usr/bin/env ruby
# Read from stdin rather than file.
file_data = $stdin.read
# Upper case title
re = /^#* .+/
file_data.gsub!(re) { |match| "*#{match.upcase}*"}
# Mutate todos
//> using scala "3.1.2"
//> using lib "co.fs2::fs2-core:3.2.7"
//> using lib "co.fs2::fs2-io:3.2.7"
//> using lib "org.http4s::http4s-core:0.23.11"
//> using lib "org.http4s::http4s-dsl:0.23.11"
//> using lib "org.http4s::http4s-ember-client:0.23.11"
import fs2.Stream
import cats.effect._
import cats.syntax.all._

** Adapted from an answer in the FS2 gitter channel by Fabio Labella: https://gitter.im/functional-streams-for-scala/fs2?at=5e962ebb6823cb38acd12ebd

What is Stream.compile and what does it do? Is it actually compiling something? Optimizing the streaming somehow?

At its core, Stream[I, O].compile is nothing more than a namespace for related methods that return the same type wrapper, I. It's not compiling anything or doing any optimization. For example, all the methods on (s: Stream[IO, Int]).compile generally have the return type IO.

In FP there is a technique of design through algebras (speaking here in the most general sense, even more general than tagless final) and it basically works like this:

  • you have some type, for example Option
  • some introduction forms (ways of getting "into" the algebra, e.g., Option.empty, Option.some; this is often referred to as "lifting" into a type)
➜ metals git:(master) pwd [I]
/Users/mhughe008/OpenSource/metals
➜ metals git:(master) git info | head [I]
## Remote URLs:
origin https://github.com/scalameta/metals.git (fetch)
origin https://github.com/scalameta/metals.git (push)
## Remote Branches:
Java System Properties:
#Wed Oct 23 18:42:54 EDT 2019
gopherProxySet=false
awt.toolkit=sun.lwawt.macosx.LWCToolkit
java.specification.version=11
sun.cpu.isalist=
sun.jnu.encoding=UTF-8
java.class.path=/usr/local/Cellar/bloop/1.3.4/bin/blp-coursier
java.vm.vendor=AdoptOpenJDK
coursier.mainJar=/usr/local/Cellar/bloop/1.3.4/bin/blp-coursier
[info] + and.scala.&.example at line 19: describe(1): OK, proved property.
[info] + and.scala.&.example at line 15: describe(-1): OK, proved property.
[info] + and.scala.&.example at line 21: describe(2): OK, proved property.
[info] + and.scala.&.example at line 17: describe(0): OK, proved property.
[info] ResponseGeneratorSpec
[info] haveHeaders should
[info] + work on value equality (377 ms)
[info] Total for specification ResponseGeneratorSpec
[info] Finished in 384 ms
[info] 1 example, 0 failure, 0 error
This file has been truncated, but you can view the full file.
Sampling process 65571 for 3 seconds with 1 millisecond of run time between samples
Sampling completed, processing symbols...
Analysis of sampling Google Chrome Helper (pid 65571) every 1 millisecond
Process: Google Chrome Helper [65571]
Path: /Applications/Google Chrome.app/Contents/Versions/30.0.1599.69/Google Chrome Helper.app/Contents/MacOS/Google Chrome Helper
Load Address: 0x4f000
Identifier: com.google.Chrome.helper
Version: 30.0.1599.69 (1599.69)
Code Type: X86 (Native)
Parent Process: Google Chrome [46125]
@matthughes
matthughes / gist:5096112
Last active December 14, 2015 13:48
Uninitialized AnyVals sneaking past your validation
final class Foo private (val value: Int) extends AnyVal {
override def toString = value.toString
}
object Foo {
def apply(value: Int) = {
assert(value > 0)
new Foo(value)
}
}
object PaulRetry {
import scalaz.stream.{ async, Process }
import scalaz.concurrent.Task
import scala.concurrent.duration._
implicit val scheduler = scalaz.stream.DefaultScheduler
/**
* Try running the process `p`, retrying in the event of failure.
* Example: `retry(Process.awakeEvery(2 minutes))(p)` will wait
* 2 minutes after each failure before trying again, indefinitely.
trait RetryCombinators {
// Taken from Paul's gist: https://gist.github.com/pchiusano/7894696
/**
* Try running the process `p`, retrying in the event of failure.
* Example: `retry(time.awakeEvery(2 minutes))(p)` will wait
* 2 minutes after each failure before trying again, indefinitely.
* Using `retry(Process.awakeEvery(2 minutes).take(5))(p)` will do
* the same, but only retry a total of five times before raising
* the latest error.