{ "cells": [ { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "(Output 'A' Done) :: forall b next. Toy Char (Toy b next)" ], "text/plain": [ "(Output 'A' Done) :: forall b next. Toy Char (Toy b next)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "(Bell (Output 'A' Done)) :: forall b1 b2 next. Toy b1 (Toy Char (Toy b2 next))" ], "text/plain": [ "(Bell (Output 'A' Done)) :: forall b1 b2 next. Toy b1 (Toy Char (Toy b2 next))" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "-- http://www.haskellforall.com/2012/06/you-could-have-invented-free-monads.html\n", "\n", "{-| \n", "data Toy b\n", " = Output b (Toy b)\n", " | Bell (Toy b)\n", " | Done\n", "-}\n", "\n", "data Toy b next =\n", " Output b next\n", " | Bell next\n", " | Done\n", " \n", "-- A simple program\n", "-- output 'A'\n", "-- done\n", ":t (Output 'A' Done)\n", "\n", "-- bell\n", "-- output 'A'\n", "-- done\n", ":t (Bell (Output 'A' Done))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "(Fix (Output 'A' (Fix Done))) :: Fix (Toy Char)" ], "text/plain": [ "(Fix (Output 'A' (Fix Done))) :: Fix (Toy Char)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "(Fix (Bell (Fix (Output 'A' (Fix Done))))) :: Fix (Toy Char)" ], "text/plain": [ "(Fix (Bell (Fix (Output 'A' (Fix Done))))) :: Fix (Toy Char)" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "data Fix f = Fix (f (Fix f))\n", "\n", ":t (Fix (Output 'A' (Fix Done)))\n", "\n", ":t (Fix (Bell (Fix (Output 'A' (Fix Done)))))\n", "\n", "-- cosine x = x\n", "-- x = 0.7...\n", "\n", "-- f x = x" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "120" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "120" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "fact' :: forall p. (Eq p, Num p) => (p -> p) -> p -> p" ], "text/plain": [ "fact' :: forall p. (Eq p, Num p) => (p -> p) -> p -> p" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "120" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "{-# LANGUAGE FlexibleContexts #-}\n", "\n", "-- https://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Monad-Fix.html\n", "import Control.Monad.Fix\n", "\n", "-- fix :: (a -> a) -> a\n", "-- fix f = let {x = f x} in x\n", "\n", "let fac n = if n <= 1 then 1 else n * fac (n-1) in fac 5\n", "\n", "fix (\\rec n -> if n <= 1 then 1 else n * rec (n-1)) 5\n", "\n", "-- fix fact' 5\n", "fact' rec n = if n == 0 then 1 else n * rec (n-1)\n", "\n", ":t fact'\n", "\n", "-- f = fact' f\n", "-- = \\n -> if n == 0 then 1 else n * f (n-1)\n", "\n", "{-|\n", " fix fact'\n", "= fact' (fix fact')\n", "= (\\rec n -> if n == 0 then 1 else n * rec (n-1)) (fix fact')\n", "= \\n -> if n == 0 then 1 else n * fix fact' (n-1)\n", "= \\n -> if n == 0 then 1 else n * fact' (fix fact') (n-1)\n", "= \\n -> if n == 0 then 1\n", " else n * (\\rec n' -> if n' == 0 then 1 else n' * rec (n'-1)) (fix fact') (n-1)\n", "= \\n -> if n == 0 then 1\n", " else n * (if n-1 == 0 then 1 else (n-1) * fix fact' (n-2))\n", "= \\n -> if n == 0 then 1\n", " else n * (if n-1 == 0 then 1\n", " else (n-1) * (if n-2 == 0 then 1\n", " else (n-2) * fix fact' (n-3)))\n", "= ...\n", "-}\n", "\n", "fix fact' 5" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "