Last active
November 14, 2017 15:00
-
-
Save lagenorhynque/4d4bde78743dc54f497ef9fe8be1820d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (ns polymorphism | |
| (:require [cats.context :as ctx] | |
| [cats.core :as m] | |
| [cats.protocols :as p] | |
| [cats.util :as util])) | |
| (defn my-map [f coll] | |
| (lazy-seq | |
| (when-let [s (seq coll)] | |
| (cons (f (first s)) | |
| (my-map f (rest s)))))) | |
| (def number-monoid | |
| (reify | |
| p/Context | |
| p/Semigroup | |
| (-mappend [_ x y] | |
| (+ x y)) | |
| p/Monoid | |
| (-mempty [_] | |
| 0))) | |
| (def list-monoid | |
| (reify | |
| p/Context | |
| p/Semigroup | |
| (-mappend [_ x y] | |
| (concat x y)) | |
| p/Monoid | |
| (-mempty [_] | |
| ()))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- パラメータ多相によるmap | |
| myMap :: (a -> b) -> [a] -> [b] | |
| myMap _ [] = [] | |
| myMap f (x:xs) = f x : myMap f xs | |
| -- アドホック多相(by 型クラス)によるmempty, mappend | |
| class MyMonoid a where | |
| myMempty :: a | |
| myMappend :: a -> a -> a | |
| instance MyMonoid Int where | |
| myMempty = 0 | |
| myMappend = (+) | |
| instance MyMonoid [a] where | |
| myMempty = [] | |
| myMappend = (++) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def myMap[A, B](f: A => B, xs: List[A]): List[B] = xs match { | |
| case Nil => Nil | |
| case y :: ys => f(y) :: myMap(f, ys) | |
| } | |
| trait MyMonoid[A] { | |
| def myMempty: A | |
| def myMappend(x: A, y: A): A | |
| } | |
| implicit def intMonoid: MyMonoid[Int] = new MyMonoid[Int] { | |
| def myMempty = 0 | |
| def myMappend(x: Int, y: Int): Int = x + y | |
| } | |
| implicit def listMonoid[A]: MyMonoid[List[A]] = new MyMonoid[List[A]] { | |
| def myMempty = Nil | |
| def myMappend(x: List[A], y: List[A]): List[A] = x ++ y | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| polymorphism=> (defn sum [coll monoid] | |
| #_=> (ctx/with-context monoid | |
| #_=> (reduce m/mappend (m/mempty) coll))) | |
| #'polymorphism/sum | |
| polymorphism=> (sum [] number-monoid) | |
| 0 | |
| polymorphism=> (sum [1 2 3] number-monoid) | |
| 6 | |
| polymorphism=> (sum [] list-monoid) | |
| () | |
| polymorphism=> (sum [[1 2] [3]] list-monoid) | |
| (1 2 3) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| > :{ | |
| | mySum :: MyMonoid a => [a] -> a | |
| | mySum = foldr myMappend myMempty | |
| | :} | |
| > mySum ([] :: [Int]) | |
| 0 | |
| > mySum ([1,2,3] :: [Int]) | |
| 6 | |
| > mySum ([] :: [[Int]]) | |
| [] | |
| > mySum ([[1,2], [3]] :: [[Int]]) | |
| [1,2,3] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| scala> def mySum[A: MyMonoid](xs: List[A]): A = xs.foldLeft(implicitly[MyMonoid[A]].myMempty)(implicitly[MyMonoid[A]].myMappend) | |
| mySum: [A](xs: List[A])(implicit evidence$1: MyMonoid[A])A | |
| scala> mySum(List[Int]()) | |
| res24: Int = 0 | |
| scala> mySum(List[Int](1,2,3)) | |
| res25: Int = 6 | |
| scala> mySum(List[List[Int]]()) | |
| res26: List[Int] = List() | |
| scala> mySum(List[List[Int]](List(1,2),List(3))) | |
| res27: List[Int] = List(1, 2, 3) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment