View comment.txt
flatten is indeed an interesting topic - one cool thing is that flatMap is just map followed by flatten, i.e. (ma flatMap f) == (ma map f flatten) [1]. | |
Another is that flatten is flatMap(identity) [2][3]. | |
Another is that a monad can be defined as a functor with a unit function (i.e. a type constructor like List or Option) and a flatten function (aka join in Haskell) [4] | |
[1] https://github.com/philipschwarz/scala-fp-combinators-code-kata/blob/master/src/main/scala/FPCombinatorsCodeKata.scala#L18 - https://www.slideshare.net/pjschwarz/scala-functional-programming-combinators-code-kata | |
[2] https://github.com/philipschwarz/scala-fp-combinators-code-kata/blob/master/src/main/scala/FPCombinatorsCodeKata.scala#L20 | |
[3] https://www.slideshare.net/pjschwarz/symmetry-in-the-interrelation-of-flatmapfoldmaptraverse-and-flattenfoldsequence | |
[4] https://www.slideshare.net/pjschwarz/monad-as-functor-with-pair-of-natural-transformations#8 |
View scala-fp-combinators-code-kata.scala
object Main extends App { | |
" SCALA FP COMBINATORS CODE KATA - start with expression 'ma flatMap f' and keep refactoring it by " | |
" applying each of the following rewrite rules in turn, until you get back to 'ma flatMap f' " | |
'①'; " flatmap can be defined in terms of map and flatten ......................................" ;'①' | |
'②'; " map can be defined in terms of flatMap and pure ........................................." ;'②' | |
'③'; " flatten can be defined in terms of flatMap and identity ................................." ;'③' | |
'④'; " chained flatMaps are equivalent to nested flatMaps (flatMap associativity law) .........." ;'④' | |
'⑤'; " Kleisli composition can be defined in terms of flatMap (apply this the other way around) " ;'⑤' | |
'⑥'; " the identity function can be defined in terms of flatten and pure ......................." ;'⑥' | |
'⑦'; " pure followed by flatten cancel each other out .........................................." ;'⑦' |
View List.map.u
base.List.map : (a ->{𝕖} b) -> [a] ->{𝕖} [b] | |
base.List.map f a = | |
go i as acc = | |
match List.at i as with | |
None -> acc | |
Some a -> | |
use Nat + | |
go (i + 1) as (acc :+ f a) | |
go 0 a [] |
View workingStateExample.u
use .base | |
use List Optional Some None drop map | |
List.head : [a] -> Optional a | |
List.head a = List.at 0 a | |
use List head | |
ability State s where | |
put : s -> {State s} () | |
get : {State s} s |
View state2.u
use .base | |
use List Optional | |
List.head : [a] -> Optional a | |
List.head a = List.at 0 a | |
ability State s where | |
put : s -> {State s} () | |
get : {State s} s |
View state.u
use .base | |
use List Optional | |
List.head : [a] -> Optional a | |
List.head a = List.at 0 a | |
ability State s where | |
put : s -> {State s} () | |
get : {State s} s |
View fruitsalad.fs
type FruitSalad = { | |
Apple: AppleVariety | |
Banana: BananaVariety | |
Cherries: CherryVariety | |
} |
View adventOfCode2019Day1.u
-- Solution to https://adventofcode.com/2019/day/1 by @philip_schwarz | |
-- Based on following solution by @runarorama: | |
-- https://gist.github.com/runarorama/21e6876bd62812b9d61a312c75ec87a3 | |
use .base | |
use .base.test.internals.v1.Test forAll | |
use .base.Test | |
-- Part 1 |
View FizzBuzz.hs
fizzbuzz :: [String] | |
fizzbuzz = | |
let fizzes = cycle ["", "", "fizz"] | |
buzzes = cycle ["", "", "", "", "buzz"] | |
pattern = zipWith (++) fizzes buzzes | |
in zipWith combine pattern [1..] where | |
combine word number = | |
if null word then show number else word |
View FoldableLaws.scala
import scalaz.std.vector.vectorMonoid | |
import scalaz.syntax.foldable.ToFoldableOps | |
import scalaz.syntax.semigroup._ | |
import scalaz.std.list.listInstance | |
// Vector append and prepend functions | |
assert( Vector(1,2) :+ 3 == Vector(1,2,3) ) | |
assert( 1 +: Vector(2,3) == Vector(1,2,3) ) |
NewerOlder