Created
December 8, 2016 09:48
-
-
Save jpablo/6ac08f5a7d7eaeab0e6e97a9e9db877b to your computer and use it in GitHub Desktop.
SICP 2.1.1: Data Abstraction
This file contains 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
data Ind = Fst | Snd | |
type Tup t = Ind -> t | |
cons x y Fst = x | |
cons x y Snd = y | |
fst' z = z Fst | |
snd' z = z Snd | |
makeRat = cons | |
numer = fst' | |
denom = snd' | |
equalRat :: (Num t, Eq t) => Tup t -> Tup t -> Bool | |
equalRat x y = numer x * denom y == numer y * denom x | |
addRat :: Num t => Tup t -> Tup t -> Tup t | |
addRat x y = makeRat ((numer x * denom y) + (numer y * denom x)) (denom x * denom y) | |
subRat :: Num t => Tup t -> Tup t -> Tup t | |
subRat x y = makeRat ((numer x * denom y) - (numer y * denom x)) (denom x * denom y) | |
print' :: Show t => Tup t -> String | |
print' z = show (numer z) ++ " / " ++ show (denom z) |
This file contains 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
package Chap2 | |
import scala.language.higherKinds | |
trait AbstractTypes { | |
type Rational[A] | |
def makeRat[A](x: A, y: A): Rational[A] | |
def numer[A](r: Rational[A]): A | |
def denom[A](r: Rational[A]): A | |
} | |
trait AbstractOps extends AbstractTypes { | |
def equalRat[A](x: Rational[A], y: Rational[A])(implicit numeric: Numeric[A]): Boolean = { | |
import numeric._ | |
numer(x) * denom(y) == numer(y) * denom(x) | |
} | |
def addRat[A](x: Rational[A], y: Rational[A])(implicit numeric: Numeric[A]): Rational[A] = { | |
import numeric._ | |
makeRat(numer(x) * denom(y) + numer(y) * denom(x), denom(x) * denom(y)) | |
} | |
} | |
object RationalsAsTuples extends AbstractOps { | |
type Rational[A] = (A,A) | |
def makeRat[A](x: A, y: A) = (x,y) | |
def numer[A](r: (A, A)): A = r._1 | |
def denom[A](r: (A, A)): A = r._2 | |
} | |
object TuplesAsFunctions extends AbstractOps { | |
sealed trait Ind | |
object Fst extends Ind | |
object Snd extends Ind | |
type Rational[A] = Ind => A | |
def cons[A](x: A, y: A) = (i: Ind) => i match { | |
case Fst => x | |
case Snd => y | |
} | |
def fst[A](z: Rational[A]) = z(Fst) | |
def snd[A](z: Rational[A]) = z(Snd) | |
def makeRat[A](x: A, y: A) = cons(x,y) | |
def numer[A](r: Rational[A]) = fst(r) | |
def denom[A](r: Rational[A]) = snd(r) | |
type Rat = Rational[Int] | |
def printRat(x: Rat) = s"${numer(x)} / ${denom(x)}" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment