Functors, Monads, Applicatives – can be so simple | de.velopmind | The Det about Programming
補足説明を加えて簡単に整理してみた。
(A => B) => (C[A] => C[B])
(A => C[B]) => (C[A] => C[B])
trait Monoid[A] { | |
def mempty: A | |
def mappend(x: A, y: A): A | |
def mconcat(xs: Seq[A]): A = xs.foldLeft(mempty)(mappend) | |
} | |
object MonoidTest { | |
def sum[A: Monoid](xs: A*): A = implicitly[Monoid[A]].mconcat(xs) | |
implicit def numericMonoid[A: Numeric] = new Monoid[A] { |
import scala.annotation.tailrec | |
object Fibonacci { | |
@tailrec | |
def fibo(i: Int, prev: BigInt = 1, curr: BigInt = 0): BigInt = i match { | |
case 0 => 0 | |
case i if i < 2 => prev + curr | |
case _ => fibo(i - 1, curr, prev + curr) | |
} |
Functors, Monads, Applicatives – can be so simple | de.velopmind | The Det about Programming
補足説明を加えて簡単に整理してみた。
(A => B) => (C[A] => C[B])
(A => C[B]) => (C[A] => C[B])
(ns random-alphanumeric-generator) | |
(def alphanumeric "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890") | |
(defn rand-alphanumeric [len] | |
(repeatedly len #(rand-nth alphanumeric))) | |
(->> (repeatedly #(rand-alphanumeric 5)) | |
(filter (fn [[a _ _ _ b]] (= a b))) | |
(map #(apply str %)) |
module WriterTest where | |
import Control.Monad.Writer (Writer, runWriter, tell) | |
gcd' :: Int -> Int -> Writer [String] Int | |
gcd' a b | |
| b == 0 = do | |
tell ["Finished with " ++ show a] | |
return a | |
| otherwise = do |
(defn my-odd? [n] | |
(letfn [(odd?? [n] | |
(if (zero? n) | |
false | |
#(even?? (dec n)))) | |
(even?? [n] | |
(if (zero? n) | |
true | |
#(odd?? (dec n))))] | |
(trampoline odd?? n))) |
(defn pow-cps-trampoline [n m] | |
(letfn [(pow [n m f] | |
(if (zero? m) | |
(f 1N) | |
(fn [] (pow n (dec m) (fn [x] #(f (* n x)))))))] | |
(trampoline pow n m identity))) | |
(do (println (pow-cps-trampoline 2 10)) | |
(println (pow-cps-trampoline 2 100)) | |
(println (pow-cps-trampoline 2 1000)) |
def sumProcedural(m: Int): Int = { | |
var sum = 0 | |
for (n <- 1 to m) { | |
sum += n | |
} | |
sum | |
} | |
def sumProcedural2(m: Int): Int = { | |
var sum = 0 |
class Rational(n: Int, d: Int) { | |
init { | |
require(d != 0, {"denominator must not be null"}) | |
} | |
private val g by lazy { gcd(Math.abs(n), Math.abs(d)) } | |
val numerator: Int by lazy { n / g } | |
val denominator: Int by lazy { d / g } | |
operator fun plus(that: Rational): Rational = | |
Rational( | |
numerator * that.denominator + that.numerator * denominator, |
@ case class UserAge(id: Int, age: Int) | |
defined class UserAge | |
@ val userAges = Map(1 -> UserAge(1, 25), 2 -> UserAge(2, 15), 3 -> UserAge(3, 35), 4 -> UserAge(4, 5), 5 -> UserAge(5, 45)) | |
userAges: Map[Int, UserAge] = Map(5 -> UserAge(5, 45), 1 -> UserAge(1, 25), 2 -> UserAge(2, 15), 3 -> UserAge(3, 35), 4 -> UserAge(4, 5)) | |
// SELECT user_age.age | |
// FROM user_age | |
// WHERE user_age.age >= 20; | |
@ userAges.filter { case (_, ua) => ua.age >= 20 }.mapValues(_.age) | |
res2: Map[Int, Int] = Map(5 -> 45, 1 -> 25, 3 -> 35) |