├── .gitignore ├── README.markdown ├── db-report ├── .gitignore ├── CHANGELOG.md ├── Readme.markdown ├── Setup.hs ├── db-report.cabal ├── main.css └── report.hs ├── depmap └── test.hs ├── hsnginx ├── Readme.md ├── cbits │ ├── Makefile │ ├── My.hs │ └── ngx_http_haskell_module.c ├── config ├── nginx.conf └── utils │ └── bootstrap.sh ├── ht-no-more ├── Bug15746.hs ├── ChangeLog.md ├── Entry.hs ├── LICENSE ├── Setup.hs ├── cpuinfo_dmalkr.txt ├── ht-no-more.cabal ├── results.txt └── wrapper.c ├── idris ├── Kats-Code │ ├── Part1 │ │ ├── intro0-tdd.ibc │ │ ├── intro0-tdd.idr │ │ ├── intro1-list.idr │ │ ├── intro2-vect.idr │ │ └── intro3-data.idr │ ├── Part2 │ │ ├── append5.idr │ │ ├── checkEq2.idr │ │ ├── checkEq4.idr │ │ ├── exactLength1.idr │ │ ├── readvec0.idr │ │ └── void3.idr │ ├── Part3 │ │ ├── Effects │ │ │ ├── Door1.idr │ │ │ ├── Door2.idr │ │ │ ├── Expr.idr │ │ │ ├── Queens.idr │ │ │ ├── Select.idr │ │ │ ├── effects_demos.ipkg │ │ │ └── hello.idr │ │ ├── Hangman │ │ │ ├── VectMissing.idr │ │ │ ├── hangman.idr │ │ │ └── hangman.ipkg │ │ ├── IO │ │ │ └── hello.idr │ │ └── Invaders │ │ │ ├── Aliens.idr │ │ │ ├── Gamestate.idr │ │ │ ├── Main.idr │ │ │ ├── Rnd.idr │ │ │ ├── SDL-idris │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── sdl.ipkg │ │ │ └── src │ │ │ │ ├── Effect │ │ │ │ └── SDL.idr │ │ │ │ ├── Graphics │ │ │ │ ├── Config.idr │ │ │ │ └── SDL.idr │ │ │ │ ├── MakefileSDLC │ │ │ │ ├── sdlrun.c │ │ │ │ └── sdlrun.h │ │ │ ├── Starfield.idr │ │ │ └── invaders.ipkg │ └── Part4 │ │ ├── Views │ │ ├── describe_list.idr │ │ ├── dlfail.idr │ │ ├── merge_sort.idr │ │ ├── merge_sort_view.idr │ │ ├── reverse.idr │ │ ├── reverse_snoc.idr │ │ └── snoclist.idr │ │ ├── infIO-stream3.idr │ │ ├── rndstream2.idr │ │ └── streams1.idr ├── hello.idr └── sort │ └── l1.idr ├── inotify ├── README.markdown └── ion.hs ├── iterative └── examples1 │ ├── conduit-1.hs │ ├── iteratee-1.hs │ ├── iteratee-2.hs │ ├── iteratee-3.hs │ ├── machines-1.hs │ ├── machines-2.hs │ ├── pipes-1.hs │ └── pipes-2.hs ├── jobs └── Main.hs ├── postgres-report ├── dynamic │ └── 00.deadlocks.sql └── static │ ├── 00.general-info.sql │ ├── 01.table-size.sql │ ├── 02.write-activity.sql │ ├── 03.life-data.sql │ ├── 04.indexes-unused.sql │ └── 05.table-read-cache-hit.sql ├── regions ├── Minimal.hs ├── SafeHandles.hs ├── SafeHandlesTEQ.hs ├── SafeHandlesTest.hs ├── info.markdown └── typed-device │ └── main.hs ├── series ├── 1.lhs └── 2.lhs ├── sum ├── post2.md.lhs ├── post3.md.lhs └── post4.md.lhs ├── talks ├── AS talk - From my son’s windows laptop to the cloud.pdf ├── cloud-haskell │ ├── 1.markdown │ ├── images │ │ ├── c-h-architecture.pdf │ │ ├── c-h-architecture.pdf_tex │ │ ├── c-h-architecture.svg │ │ ├── c-h-architecture.xml │ │ ├── c-h-d-p │ │ ├── c-h-d-p.png │ │ ├── c-h-d-p.svg │ │ ├── c-h-n-t.png │ │ ├── c-h-n-t.svg │ │ └── c-h-n-t.xml │ ├── talk.pdf │ └── talk.tex ├── ffi │ ├── presentation │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── CONTRIBUTING.md │ │ ├── Gruntfile.js │ │ ├── LICENSE │ │ ├── README.md │ │ ├── bower.json │ │ ├── css │ │ │ ├── print │ │ │ │ ├── paper.css │ │ │ │ └── pdf.css │ │ │ ├── reveal.css │ │ │ ├── reveal.scss │ │ │ └── theme │ │ │ │ ├── README.md │ │ │ │ ├── beige.css │ │ │ │ ├── black.css │ │ │ │ ├── blood.css │ │ │ │ ├── league.css │ │ │ │ ├── moon.css │ │ │ │ ├── night.css │ │ │ │ ├── serif.css │ │ │ │ ├── simple.css │ │ │ │ ├── sky.css │ │ │ │ ├── solarized.css │ │ │ │ ├── source │ │ │ │ ├── beige.scss │ │ │ │ ├── black.scss │ │ │ │ ├── blood.scss │ │ │ │ ├── league.scss │ │ │ │ ├── moon.scss │ │ │ │ ├── night.scss │ │ │ │ ├── serif.scss │ │ │ │ ├── simple.scss │ │ │ │ ├── sky.scss │ │ │ │ ├── solarized.scss │ │ │ │ └── white.scss │ │ │ │ ├── template │ │ │ │ ├── mixins.scss │ │ │ │ ├── settings.scss │ │ │ │ └── theme.scss │ │ │ │ └── white.css │ │ ├── index.html │ │ ├── js │ │ │ └── reveal.js │ │ ├── lib │ │ │ ├── css │ │ │ │ └── zenburn.css │ │ │ ├── font │ │ │ │ ├── league-gothic │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── league-gothic.css │ │ │ │ │ ├── league-gothic.eot │ │ │ │ │ ├── league-gothic.ttf │ │ │ │ │ └── league-gothic.woff │ │ │ │ └── source-sans-pro │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── source-sans-pro-italic.eot │ │ │ │ │ ├── source-sans-pro-italic.ttf │ │ │ │ │ ├── source-sans-pro-italic.woff │ │ │ │ │ ├── source-sans-pro-regular.eot │ │ │ │ │ ├── source-sans-pro-regular.ttf │ │ │ │ │ ├── source-sans-pro-regular.woff │ │ │ │ │ ├── source-sans-pro-semibold.eot │ │ │ │ │ ├── source-sans-pro-semibold.ttf │ │ │ │ │ ├── source-sans-pro-semibold.woff │ │ │ │ │ ├── source-sans-pro-semibolditalic.eot │ │ │ │ │ ├── source-sans-pro-semibolditalic.ttf │ │ │ │ │ ├── source-sans-pro-semibolditalic.woff │ │ │ │ │ └── source-sans-pro.css │ │ │ └── js │ │ │ │ ├── classList.js │ │ │ │ ├── head.min.js │ │ │ │ └── html5shiv.js │ │ ├── plugin │ │ │ ├── highlight │ │ │ │ └── highlight.js │ │ │ ├── markdown │ │ │ │ ├── example.html │ │ │ │ ├── example.md │ │ │ │ ├── markdown.js │ │ │ │ └── marked.js │ │ │ ├── math │ │ │ │ └── math.js │ │ │ ├── multiplex │ │ │ │ ├── client.js │ │ │ │ ├── index.js │ │ │ │ └── master.js │ │ │ ├── notes-server │ │ │ │ ├── client.js │ │ │ │ ├── index.js │ │ │ │ └── notes.html │ │ │ ├── notes │ │ │ │ ├── notes.html │ │ │ │ └── notes.js │ │ │ ├── print-pdf │ │ │ │ └── print-pdf.js │ │ │ ├── search │ │ │ │ └── search.js │ │ │ └── zoom-js │ │ │ │ └── zoom.js │ │ └── test │ │ │ ├── examples │ │ │ ├── assets │ │ │ │ ├── image1.png │ │ │ │ └── image2.png │ │ │ ├── barebones.html │ │ │ ├── embedded-media.html │ │ │ ├── math.html │ │ │ ├── slide-backgrounds.html │ │ │ └── slide-transitions.html │ │ │ ├── qunit-1.12.0.css │ │ │ ├── qunit-1.12.0.js │ │ │ ├── test-markdown-element-attributes.html │ │ │ ├── test-markdown-element-attributes.js │ │ │ ├── test-markdown-slide-attributes.html │ │ │ ├── test-markdown-slide-attributes.js │ │ │ ├── test-markdown.html │ │ │ ├── test-markdown.js │ │ │ ├── test-pdf.html │ │ │ ├── test-pdf.js │ │ │ ├── test.html │ │ │ └── test.js │ ├── programs │ │ ├── 7.hs │ │ ├── capi │ │ │ ├── Makefile │ │ │ ├── pi.c │ │ │ ├── pi.h │ │ │ ├── test.hs │ │ │ └── test2.hs │ │ ├── fork-on-simple.hs │ │ ├── gperf │ │ │ ├── Makefile │ │ │ ├── bench.hs │ │ │ ├── gperf.c │ │ │ ├── table.1.c │ │ │ └── table.c │ │ ├── rts-signal │ │ │ ├── Makefile │ │ │ ├── bogus.c │ │ │ ├── bogus.h │ │ │ └── test.hs │ │ ├── safe-vs-unsafe-bench │ │ │ ├── Makefile │ │ │ └── bench.hs │ │ └── unsafe-bottom │ │ │ ├── Makefile │ │ │ ├── bottom.c │ │ │ └── runit.hs │ ├── talk.org │ └── thread-local-storage.org └── fpure-capabilities-final.pdf ├── typelevel-comp └── composable.hs └── typelevel-literals ├── Main.hs ├── Proof.lhs ├── README.markdown ├── TypeLevelFloat.hs ├── TypeLevelRatio.hs └── relalg └── RelAlg.lhs /.gitignore: -------------------------------------------------------------------------------- 1 | *.ibc 2 | *.o 3 | *.hi 4 | *~ 5 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # A repository with random projects. 2 | -------------------------------------------------------------------------------- /db-report/.gitignore: -------------------------------------------------------------------------------- 1 | tmp 2 | *.hi 3 | *.dyn_o 4 | *.dyn_hi 5 | 6 | -------------------------------------------------------------------------------- /db-report/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Revision history for db-report 2 | 3 | ## 0.1.0.0 -- YYYY-mm-dd 4 | 5 | * First version. Released on an unsuspecting world. 6 | -------------------------------------------------------------------------------- /db-report/Readme.markdown: -------------------------------------------------------------------------------- 1 | # Utility to build information about use of the postgres database. 2 | 3 | 4 | A small tool that connects to the database and gather differrent kind 5 | of statistics, like table and index sizes, cache hit rate, index usage. 6 | 7 | The tool is not yet complete as in this state it's enough for my needs 8 | at work, but I'll continue working on that and slowly improving it. 9 | 10 | 1. How to run: 11 | 12 | ``` 13 | nix-shell -p "haskellPackages.ghcWithPackages (p: [p.hasql p.lens ])" 14 | ``` 15 | 16 | In the shell run 17 | 18 | ``` 19 | export PG_HOST=postgresql://user:password@host:port/database 20 | ghci report.hs -package hasql -package lens -package colonnade -package blaze-html -package blaze-markup -package vector -package text-show -package scientific -package foldl -Wall 21 | ``` 22 | 23 | Unfortunately blaze-colonnade and hasql-th do not build under nixos 24 | of the specific version. But patches that will either fix nixpkgs 25 | or add shell.nix will be kindly accepted. 26 | -------------------------------------------------------------------------------- /db-report/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /db-report/db-report.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: >=1.10 2 | -- Initial package description 'db-report.cabal' generated by 'cabal init'. 3 | -- For further documentation, see http://haskell.org/cabal/users-guide/ 4 | 5 | name: db-report 6 | version: 0.1.0.0 7 | -- synopsis: 8 | -- description: 9 | -- bug-reports: 10 | -- license: 11 | license-file: LICENSE 12 | author: Alexander Vershilov 13 | maintainer: alexander.vershilov@sirius.online 14 | -- copyright: 15 | -- category: 16 | build-type: Simple 17 | extra-source-files: CHANGELOG.md, Readme.markdown 18 | 19 | executable db-report 20 | main-is: report.hs 21 | -- other-modules: 22 | -- other-extensions: 23 | build-depends: base >=4.13 && <4.14, 24 | blaze-colonnade, 25 | blaze-html, 26 | blaze-markup, 27 | bytestring, 28 | colonnade, 29 | filepath, 30 | foldl, 31 | lens, 32 | hasql, 33 | hasql-th, 34 | scientific, 35 | text, 36 | text-show, 37 | vector 38 | -- hs-source-dirs: 39 | default-language: Haskell2010 40 | -------------------------------------------------------------------------------- /db-report/main.css: -------------------------------------------------------------------------------- 1 | table { 2 | flex-wrap: wrap; 3 | margin: 0 auto; 4 | padding: 2rem 0rem 0rem 0rem; 5 | } 6 | 7 | 8 | table td, table th { 9 | box-sizing: border-box; 10 | flex-grow: 1; 11 | padding: 0.8em 1.2em; 12 | overflow: hidden; 13 | list-style-type: none; 14 | outline: 1px solid #ddd; 15 | text-align: center; 16 | font-weight: 300; 17 | margin: { 18 | top: 1px; 19 | left: 1px; 20 | } 21 | } 22 | 23 | td.number { 24 | text-align:right 25 | } 26 | 27 | td.module { 28 | text-align: left; 29 | font-weight: bold; 30 | } 31 | 32 | table td.lev1 { 33 | background-color: yellow; 34 | } 35 | 36 | table td.lev2 { 37 | background-color: orange; 38 | } 39 | 40 | table td.lev3 { 41 | background-color: rgba(255,0,0,0.75); 42 | } 43 | -------------------------------------------------------------------------------- /depmap/test.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE GADTs, MagicHash #-} 2 | import Data.Dependent.Map as D 3 | import Data.GADT.Compare 4 | 5 | import Unsafe.Coerce 6 | 7 | import GHC.Generics 8 | import GHC.Prim 9 | import GHC.Types 10 | 11 | data Hint a where 12 | HintPort :: Hint Int 13 | HintHost :: Hint String 14 | HintTeapot :: Hint Int 15 | 16 | dataToTag x = I# (dataToTag# x) 17 | 18 | instance GEq Hint where 19 | a `geq` b 20 | | dataToTag a == dataToTag b = Just (unsafeCoerce Refl) 21 | | otherwise = Nothing 22 | 23 | instance GCompare Hint where 24 | 25 | test :: DMap Hint 26 | test = D.insert HintTeapot 7 $ D.insert HintPort 99 $ D.insert HintPort 7 D.empty 27 | -------------------------------------------------------------------------------- /hsnginx/Readme.md: -------------------------------------------------------------------------------- 1 | Attempt to try to write modules for NGINX using haskell 2 | 3 | This work is far from completions. Following things are 4 | required at least: 5 | 1. Implement bindings to more nginx functions 6 | 2. Automate building process 7 | 8 | How to build: 9 | 1. bootstrap project using utils/bootstrap.sh that will download 10 | nginx and try to run bootstrap make 11 | 2. Buiding will fail because nginx will be built with cc, not ghc. 12 | 3. go to cbits folder and run Makefile in order to build haskell 13 | project 14 | 4. copy .o files to relevant place in vendor/nginx-\*/objs/ and 15 | try to build nginx again. 16 | -------------------------------------------------------------------------------- /hsnginx/cbits/Makefile: -------------------------------------------------------------------------------- 1 | GHC=ghc 2 | NGNX_PATH=../vendor/nginx-1.9.6/ 3 | NGNX_INCLUDES=-I$(NGNX_PATH)/src/ -I$(NGNX_PATH)/src/core -I$(NGNX_PATH)/src/event -I$(NGNX_PATH)/src/http -I$(NGNX_PATH)/src/os/unix -I$(NGNX_PATH)/objs -I$(NGNX_PATH)/src/http/modules 4 | 5 | all: My.o ngx_http_haskell_module.o test.o 6 | 7 | 8 | test.o: My.o ngx_http_haskell_module.o 9 | ld -r -o test.o My.o ngx_http_haskell_module.o \ 10 | /usr/lib64/ghc-7.10.2/rts/libHSrts.a \ 11 | /usr/lib64/ghc-7.10.2/base_GDytRqRVSUX7zckgKqJjgw/libHSbase-4.8.1.0-GDytRqRVSUX7zckgKqJjgw.a \ 12 | /usr/lib64/ghc-7.10.2/ghcpr_8TmvWUcS1U1IKHT0levwg3/libHSghc-prim-0.4.0.0-8TmvWUcS1U1IKHT0levwg3.a \ 13 | /usr/lib64/ghc-7.10.2/integ_2aU3IZNMF9a7mQ0OzsZ0dS/libHSinteger-gmp-1.0.0.0-2aU3IZNMF9a7mQ0OzsZ0dS.a \ 14 | 15 | #-lpthread -ldl -lrt -lHSrts -lffi -L/usr/lib64/ghc-7.10.2/rts/ 16 | 17 | 18 | My.o: My.hs 19 | $(GHC) -c -static $< $(NGNX_INCLUDES) 20 | 21 | ngx_http_haskell_module.o: ngx_http_haskell_module.c My.o 22 | $(GHC) -c -static $< My.o $(NGNX_INCLUDES) 23 | -------------------------------------------------------------------------------- /hsnginx/cbits/My.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CApiFFI #-} 2 | {-# LANGUAGE ForeignFunctionInterface #-} 3 | module My where 4 | 5 | import Foreign.Ptr 6 | import Foreign.C 7 | import Foreign.C.String 8 | import Foreign.Marshal.Array 9 | 10 | 11 | foreign export ccall fac :: Int -> Int 12 | foreign export ccall reverseIt :: Ptr Pool -> CString -> Int -> IO (Ptr NgxString) 13 | 14 | fac 0 = 1 15 | fac i = i * fac (i-1) 16 | 17 | data Pool = Pool 18 | 19 | foreign import ccall unsafe "core/ngx_palloc.h ngx_pcalloc" 20 | ngx_pcalloc :: Ptr Pool -> CSize -> IO (Ptr a) 21 | 22 | newtype NgxString = NgxString () 23 | 24 | reverseIt :: Ptr Pool -> CString -> Int -> IO (Ptr NgxString) 25 | reverseIt pool s l = do 26 | s <- peekCStringLen (s, l) 27 | withCStringLen (reverse s) $ \(ptr, len) -> do 28 | cptr <- ngx_pcalloc pool (fromIntegral len) 29 | copyArray cptr ptr len 30 | return (castPtr cptr) 31 | 32 | 33 | -------------------------------------------------------------------------------- /hsnginx/config: -------------------------------------------------------------------------------- 1 | ngx_feature="Haskell module" 2 | ngx_addon_name=ngx_http_haskell_module 3 | HTTP_MODULES="$HTTP_MODULES ngx_http_haskell_module" 4 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS \ 5 | $ngx_addon_dir/cbits/ngx_http_haskell_module.c" 6 | -------------------------------------------------------------------------------- /hsnginx/nginx.conf: -------------------------------------------------------------------------------- 1 | events { 2 | worker_connections 1024; 3 | } 4 | 5 | http { 6 | server { 7 | listen 8080; 8 | server_name localhost; 9 | 10 | location / { 11 | hello 'Hello World'; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /hsnginx/utils/bootstrap.sh: -------------------------------------------------------------------------------- 1 | DIR=$(pwd) 2 | BUILDDIR=${DIR}/build 3 | NGINX_DIR=nginx # TODO: default that 4 | NGINX_VERSION=1.9.6 # TODO: default that 5 | 6 | clean() { 7 | rm -rf build vendor 8 | } 9 | 10 | setup_local_directories () { 11 | if [ ! -d $BUILDDIR ]; then 12 | mkdir $BUILDDIR > /dev/null 2>&1 13 | mkdir $BUILDDIR/$NGINX_DIR > /dev/null 2>&1 14 | fi 15 | 16 | if [ ! -d "vendor" ]; then 17 | mkdir vendor > /dev/null 2>&1 18 | fi 19 | } 20 | 21 | install_nginx () { 22 | if [ ! -d "vendor/nginx-$NGINX_VERSION" ]; then 23 | pushd vendor > /dev/null 2>&1 24 | curl -s -L -O "http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz" 25 | tar xzf "nginx-$NGINX_VERSION.tar.gz" 26 | pushd "nginx-$NGINX_VERSION" > /dev/null 2>&1 27 | ./configure \ 28 | --with-debug \ 29 | --prefix=$(pwd)/../../build/nginx \ 30 | --conf-path=conf/nginx.conf \ 31 | --add-module=${DIR} \ 32 | --error-log-path=logs/error.log \ 33 | --http-log-path=logs/access.log 34 | make 35 | make install 36 | popd > /dev/null 2>&1 37 | popd > /dev/null 2>&1 38 | ln -sf $(pwd)/nginx.conf $(pwd)/build/nginx/conf/nginx.conf 39 | else 40 | printf "NGINX already installed\n" 41 | fi 42 | } 43 | 44 | 45 | if [[ "$#" -eq 1 ]]; then 46 | if [[ "$1" == "clean" ]]; then 47 | clean 48 | else 49 | echo "clean is the only option" 50 | fi 51 | else 52 | setup_local_directories 53 | install_nginx 54 | fi 55 | -------------------------------------------------------------------------------- /ht-no-more/Bug15746.hs: -------------------------------------------------------------------------------- 1 | import Data.ByteString.Builder.Extra (defaultChunkSize) 2 | import Data.Function 3 | import System.IO 4 | import qualified Data.ByteString as BS 5 | 6 | main :: IO () 7 | main = do 8 | h <- openFile "big_file" ReadMode 9 | fix $ \loop -> do 10 | bs <- BS.hGetSome h defaultChunkSize 11 | if BS.null bs 12 | then pure () 13 | else do 14 | print bs 15 | loop 16 | -------------------------------------------------------------------------------- /ht-no-more/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # Revision history for ht-no-more 2 | 3 | ## 0.1.0.0 -- YYYY-mm-dd 4 | 5 | * First version. Released on an unsuspecting world. 6 | -------------------------------------------------------------------------------- /ht-no-more/Entry.hs: -------------------------------------------------------------------------------- 1 | -- We can call this module Main due to 2 | -- 3 | -- @ 4 | -- Main.hs:1:1: error: 5 | -- The IO action ‘main’ is not defined in module ‘Main’ 6 | -- @ 7 | module Entry where 8 | 9 | import Control.Concurrent 10 | import Data.ByteString.Builder.Extra (defaultChunkSize) 11 | import Data.Function 12 | import System.IO 13 | import qualified Data.ByteString as BS 14 | 15 | entry :: IO () 16 | entry = do 17 | print =<< getNumCapabilities 18 | h <- openFile "big_file" ReadMode 19 | fix $ \loop -> do 20 | bs <- BS.hGetSome h defaultChunkSize 21 | if BS.null bs 22 | then pure () 23 | else do 24 | print bs 25 | loop 26 | -------------------------------------------------------------------------------- /ht-no-more/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /ht-no-more/ht-no-more.cabal: -------------------------------------------------------------------------------- 1 | name: ht-no-more 2 | version: 0.1.0.0 3 | -- synopsis: 4 | -- description: 5 | license: MPL-2.0 6 | license-file: LICENSE 7 | author: Alexander Vershilov 8 | maintainer: alexander.vershilov@gmail.com 9 | -- copyright: 10 | -- category: 11 | build-type: Simple 12 | extra-source-files: ChangeLog.md 13 | cabal-version: >=1.10 14 | 15 | executable ht-no-more 16 | main-is: wrapper.c 17 | other-modules: Entry 18 | -- other-extensions: 19 | build-depends: base >=4.10 && <4.12 20 | , bytestring 21 | -- hs-source-dirs: 22 | default-language: Haskell2010 23 | 24 | -- we can't cheat now, we must process options on our own 25 | -- Warning: -rtsopts and -with-rtsopts have no effect with -no-hs-main. 26 | -- Call hs_init_ghc() from your main() function to set these options. 27 | ghc-options: -no-hs-main 28 | -threaded 29 | -optl-Wl,-wrap,getNumberOfProcessors 30 | 31 | -- 32 | -- Just original bug https://ghc.haskell.org/trac/ghc/ticket/15746 33 | -- 34 | executable bug15746 35 | main-is: Bug15746.hs 36 | build-depends: base >=4.10 && <4.12 37 | , bytestring 38 | default-language: Haskell2010 39 | ghc-options: -threaded -rtsopts 40 | -------------------------------------------------------------------------------- /ht-no-more/results.txt: -------------------------------------------------------------------------------- 1 | GHC 8.4.3 2 | 3 | "big_file" generation: 4 | % yes "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq" | head -n 1000000 > big_file 5 | 6 | CPU info: see cpuinfo_dmalkr.txt 7 | 8 | --- Results: --- 9 | 10 | 11 | bug15476 -N1: ok 12 | ------------------------------------------------------------ 13 | % cabal build bug15746 > /dev/null && /usr/bin/time dist/build/bug15746/bug15746 +RTS -M2M -N1 > /dev/null && echo ok 14 | 0.60user 0.00system 0:00.52elapsed 117%CPU (0avgtext+0avgdata 5964maxresident)k 15 | 0inputs+0outputs (0major+678minor)pagefaults 0swaps 16 | ok 17 | ------------------------------------------------------------ 18 | 19 | 20 | bug15476 -N2: fail 21 | ------------------------------------------------------------ 22 | % cabal build bug15746 > /dev/null && /usr/bin/time dist/build/bug15746/bug15746 +RTS -M2M -N2 > /dev/null && echo ok 23 | bug15746: Heap exhausted; 24 | bug15746: Current maximum heap size is 2097152 bytes (2 MB). 25 | bug15746: Use `+RTS -M' to increase it. 26 | Command exited with non-zero status 251 27 | 0.01user 0.00system 0:00.01elapsed 109%CPU (0avgtext+0avgdata 7000maxresident)k 28 | 0inputs+0outputs (0major+508minor)pagefaults 0swaps 29 | ------------------------------------------------------------ 30 | 31 | 32 | ht-no-more -N1: ok 33 | ------------------------------------------------------------ 34 | % cabal build ht-no-more > /dev/null && /usr/bin/time dist/build/ht-no-more/ht-no-more +RTS -M2M -N1 > /dev/null && echo ok 35 | 0 real core - enabling 36 | 1 is virual - skipping 37 | 2 real core - enabling 38 | 3 is virual - skipping 39 | 4 real core - enabling 40 | 5 is virual - skipping 41 | 6 real core - enabling 42 | 7 is virual - skipping 43 | 8 real core - enabling 44 | 9 is virual - skipping 45 | 10 real core - enabling 46 | 11 is virual - skipping 47 | 12 real core - enabling 48 | 13 is virual - skipping 49 | 14 real core - enabling 50 | 15 is virual - skipping 51 | Define number of affinities as 8 52 | 0.56user 0.00system 0:00.53elapsed 106%CPU (0avgtext+0avgdata 5932maxresident)k 53 | 0inputs+0outputs (0major+678minor)pagefaults 0swaps 54 | ok 55 | ------------------------------------------------------------ 56 | 57 | 58 | ht-no-more -N2: fail 59 | ------------------------------------------------------------ 60 | 0 real core - enabling 61 | 1 is virual - skipping 62 | 2 real core - enabling 63 | 3 is virual - skipping 64 | 4 real core - enabling 65 | 5 is virual - skipping 66 | 6 real core - enabling 67 | 7 is virual - skipping 68 | 8 real core - enabling 69 | 9 is virual - skipping 70 | 10 real core - enabling 71 | 11 is virual - skipping 72 | 12 real core - enabling 73 | 13 is virual - skipping 74 | 14 real core - enabling 75 | 15 is virual - skipping 76 | Define number of affinities as 8 77 | ht-no-more: internal error: getTopHandlerThread: neither a WEAK nor a DEAD_WEAK: 0x6d3378 0x444450 2659416 78 | (GHC version 8.4.3 for x86_64_unknown_linux) 79 | Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug 80 | Command terminated by signal 6 81 | 0.00user 0.00system 0:00.01elapsed 22%CPU (0avgtext+0avgdata 5012maxresident)k 82 | 0inputs+0outputs (0major+499minor)pagefaults 0swaps 83 | ------------------------------------------------------------ 84 | 85 | -------------------------------------------------------------------------------- /ht-no-more/wrapper.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "HsFFI.h" 7 | 8 | #ifdef __GLASGOW_HASKELL__ 9 | //#include "Entry_stub.h" 10 | #include "Rts.h" 11 | #endif 12 | 13 | static uint32_t procno = 0; 14 | 15 | StgClosure Entry_entry_closure; 16 | uint32_t __real_getNumberOfProcessors(void); 17 | 18 | uint32_t __wrap_getNumberOfProcessors(void) 19 | { 20 | if (procno==0) { 21 | return __real_getNumberOfProcessors(); 22 | } else { 23 | return procno; 24 | } 25 | } 26 | 27 | int setcpus() { 28 | cpu_set_t set; 29 | CPU_ZERO(&set); 30 | FILE *cpuinfo = fopen("/proc/cpuinfo", "rb"); 31 | char *arg = 0; 32 | size_t size = 0; 33 | int ret = 0; 34 | int current_cpu = -1; 35 | int current_core = -1; 36 | int cpu_count = 0; 37 | 38 | ret = sched_getaffinity(0, sizeof(cpu_set_t), &set); 39 | if (ret == -1) { 40 | fprintf(stderr, "Error: failed to get cpu affinity"); 41 | return 0; 42 | } 43 | 44 | while(getdelim(&arg, &size, '\n', cpuinfo) != -1) 45 | { 46 | if (strstr(arg, "core id") != NULL) { 47 | current_core++; 48 | char * found = strchr(arg, ':'); 49 | if (found) { 50 | int cpu = atoi(found+1); 51 | if (current_cpu != cpu) { 52 | current_cpu++; 53 | if (CPU_ISSET(current_core, &set)) { 54 | CPU_SET(current_core, &set); // XXX: this is noop. 55 | fprintf(stderr, "%i real core - enabling\n", current_core); 56 | cpu_count++; 57 | } else { 58 | fprintf(stderr, "%i was disabled - skipping\n", current_core); 59 | } 60 | } else { 61 | fprintf(stderr, "%i is virual - skipping\n", current_core); 62 | CPU_CLR(current_core, &set); 63 | } 64 | } else { 65 | return 1; 66 | } 67 | } 68 | } 69 | ret = sched_setaffinity(0, sizeof(cpu_set_t), &set); 70 | if (ret == -1) { 71 | fprintf(stderr, "Error: failed to set affinities - falling back to default procedure\n"); 72 | procno = 0; 73 | } else { 74 | fprintf(stderr, "Define number of affinities as %i\n", cpu_count); 75 | procno = cpu_count; 76 | } 77 | free(arg); 78 | fclose(cpuinfo); 79 | return 0; 80 | } 81 | 82 | int main(int argc, char * argv[]) { 83 | setcpus(); 84 | int exit_status; 85 | SchedulerStatus status; 86 | #if __GLASGOW_HASKELL__ >= 703 87 | { 88 | RtsConfig conf = defaultRtsConfig; 89 | conf.rts_opts_enabled = RtsOptsAll; 90 | hs_init_ghc(&argc, &argv, conf); 91 | } 92 | #else 93 | hs_init(&argc, &argv); 94 | #endif 95 | hs_init(&argc, &argv); 96 | { 97 | Capability *cap = rts_lock(); 98 | rts_evalLazyIO(&cap, &Entry_entry_closure, NULL); 99 | status = rts_getSchedStatus(cap); 100 | rts_unlock(cap); 101 | } 102 | // check the status of the entire Haskell computation 103 | switch (status) { 104 | case Killed: 105 | errorBelch("main thread exited (uncaught exception)"); 106 | exit_status = EXIT_KILLED; 107 | break; 108 | case Interrupted: 109 | errorBelch("interrupted"); 110 | exit_status = EXIT_INTERRUPTED; 111 | break; 112 | case HeapExhausted: 113 | exit_status = EXIT_HEAPOVERFLOW; 114 | break; 115 | case Success: 116 | exit_status = EXIT_SUCCESS; 117 | break; 118 | default: 119 | barf("main thread completed with invalid status"); 120 | } 121 | hs_exit(); 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part1/intro0-tdd.ibc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/idris/Kats-Code/Part1/intro0-tdd.ibc -------------------------------------------------------------------------------- /idris/Kats-Code/Part1/intro0-tdd.idr: -------------------------------------------------------------------------------- 1 | 2 | -- Example 1: Types are first class; compute/manipulate types 3 | 4 | StringOrNat : (isStr : Bool) -> Type 5 | StringOrNat False = String 6 | StringOrNat True = Nat 7 | 8 | -- Example 2: Types of one thing can influence types of another 9 | 10 | lengthOrDouble : (isStr : Bool) -> StringOrNat isStr -> Nat 11 | lengthOrDouble False s = length s 12 | lengthOrDouble True i = i*2 13 | 14 | 15 | 16 | 17 | -- lengthOrDouble' : (isStr : Bool) -> ?result -> Nat 18 | -- lengthOrDouble' = lengthOrDouble 19 | 20 | 21 | 22 | 23 | -- Example 3: Formatted output (Type safe printf) 24 | 25 | data Format = Number Format 26 | | Str Format 27 | | Lit String Format 28 | | End 29 | 30 | %name Format fmt 31 | 32 | printfTy : Format -> Type 33 | printfTy (Number f) = (i : Int) -> printfTy f 34 | printfTy (Str f) = (str : String) -> printfTy f 35 | printfTy (Lit str f) = printfTy f 36 | printfTy End = String 37 | 38 | printf_aux : (f : Format) -> String -> printfTy f 39 | printf_aux (Number fmt) x = \i => printf_aux fmt (x ++ show i) 40 | printf_aux (Str fmt) x = \str => printf_aux fmt (x ++ str) 41 | printf_aux (Lit y fmt) x = printf_aux fmt (x ++ y) 42 | printf_aux End x = x 43 | 44 | 45 | format' : List Char -> Format 46 | format' [] = End 47 | format' ('%' :: 'd' :: xs) = Number (format' xs) 48 | format' ('%' :: 's' :: xs) = Str (format' xs) 49 | format' ('%' :: xs) = Lit "%" (format' xs) 50 | format' (x :: xs) with (format' xs) 51 | format' (x :: xs) | (Lit str f) = Lit (strCons x str) f 52 | format' (x :: xs) | fmt = Lit (strCons x "") fmt 53 | 54 | format : String -> Format 55 | format str = format' (unpack str) 56 | 57 | printf : (f : String) -> printfTy (format f) 58 | printf f = printf_aux (format f) "" 59 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part1/intro1-list.idr: -------------------------------------------------------------------------------- 1 | {- Definition from the Prelude: 2 | 3 | infixr 5 :: 4 | 5 | data List a = Nil | (::) a (List a) 6 | -} 7 | 8 | my_append : List a -> List a -> List a 9 | my_append Nil a = a 10 | my_append (a :: as) bs = a :: my_append as bs 11 | 12 | my_map : (a -> b) -> List a -> List b 13 | my_map f Nil = Nil 14 | my_map f (a :: as) = f a :: my_map f as 15 | 16 | my_zipWith : (a -> b -> c) -> List a -> List b -> List c 17 | my_zipWith f (a :: as) (b :: bs) = f a b :: my_zipWith f as bs 18 | my_zipWith _ _ _ = Nil 19 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part1/intro2-vect.idr: -------------------------------------------------------------------------------- 1 | {- 2 | data Nat = Z | S Nat 3 | 4 | (+) : Nat -> Nat -> Nat 5 | Z + y = y 6 | (S x) + y = S (plus x y) 7 | -} 8 | 9 | data Vect : Nat -> Type -> Type where 10 | Nil : Vect Z a 11 | (::) : a -> Vect k a -> Vect (S k) a 12 | 13 | %name Vect xs, ys, zs 14 | 15 | 16 | append : Vect n a -> Vect m a -> Vect (n + m) a 17 | append Nil v = v 18 | append (a :: as) v = a :: append as v 19 | 20 | 21 | zipWith : (a -> b -> c) -> Vect n a -> Vect n b -> Vect n c 22 | zipWith f (a :: as) (b :: bs) = f a b :: zipWith f as bs 23 | zipWith _ Nil Nil = Nil 24 | 25 | zip : Vect n a -> Vect n b -> Vect n (a, b) 26 | zip as bs = Main.zipWith (\a, b => (a,b)) as bs 27 | 28 | mkvec : {m:Nat} -> Vect m (Vect Z elem) 29 | mkvec {m=Z} = Nil 30 | mkvec {m=S k} = Nil :: mkvec 31 | 32 | transpose_vec : Vect n (Vect m elem) -> Vect m (Vect n elem) 33 | transpose_vec Nil = mkvec 34 | transpose_vec (x :: xs) = zipWith (::) x (transpose_vec xs) 35 | 36 | 37 | n0 : Vect 0 Nat 38 | n0 = Nil 39 | 40 | n1 : Vect 1 Nat 41 | n1 = 1 :: Nil 42 | 43 | 44 | 45 | 46 | 47 | ------- A main program to read dimensions, generate and tranpose a vector 48 | 49 | Functor (Vect m) where 50 | map m [] = [] 51 | map m (x :: xs) = m x :: map m xs 52 | 53 | Show a => Show (Vect m a) where 54 | show x = show (toList x) 55 | where 56 | toList : Vect m a -> List a 57 | toList [] = [] 58 | toList (y :: xs) = y :: toList xs 59 | 60 | countTo : (m : Nat) -> Vect m Int 61 | countTo Z = [] 62 | countTo (S k) = 0 :: map (+1) (countTo k) 63 | 64 | mkVect : (n, m : Nat) -> Vect n (Vect m Int) 65 | mkVect Z m = [] 66 | mkVect (S k) m = countTo m :: map (map (+ cast m)) (mkVect k m) 67 | 68 | main : IO () 69 | main = do putStr "Rows: " 70 | let r : Nat = cast (cast {to=Int} !getLine) 71 | putStr "Columns: " 72 | let c : Nat = cast (cast {to=Int} !getLine) 73 | printLn (mkVect r c) 74 | putStrLn "Transposed:" 75 | printLn (transpose_vec (mkVect r c)) 76 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part1/intro3-data.idr: -------------------------------------------------------------------------------- 1 | data Tree a = Empty 2 | | Node (Tree a) a (Tree a) 3 | 4 | insert : Ord a => a -> Tree a -> Tree a 5 | insert a Empty = Node Empty a Empty 6 | insert a (Node l b r) = 7 | if a <= b 8 | then Node (insert a l) b r 9 | else Node l b (insert a r) 10 | 11 | data Expr = Add Expr Expr 12 | | Sub Expr Expr 13 | | Mul Expr Expr 14 | | Value Int 15 | 16 | evaluate : Expr -> Int 17 | evaluate (Add e1 e2) = evaluate e1 + evaluate e2 18 | evaluate (Sub e1 e2) = evaluate e1 - evaluate e2 19 | evaluate (Mul e1 e2) = evaluate e1 * evaluate e2 20 | evaluate (Value i) = i 21 | 22 | 23 | 24 | data PowerSource = Petrol | Pedal 25 | 26 | data Vehicle : PowerSource -> Type where 27 | Bicycle : Vehicle Pedal 28 | Car : (fuel : Nat) -> Vehicle Petrol 29 | Bus : (fuel : Nat) -> Vehicle Petrol 30 | 31 | 32 | wheels : Vehicle power -> Nat 33 | wheels Bycycle = 2 34 | wheels (Car _) = 4 35 | wheels (Bus _) = 6 36 | 37 | 38 | refuel : Vehicle Petrol -> Vehicle Petrol 39 | refuel (Car _) = Car 100 40 | refuel (Bus _) = Bus 100 41 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part2/append5.idr: -------------------------------------------------------------------------------- 1 | import Data.Vect 2 | 3 | append : Vect n elem -> Vect m elem -> Vect (n + m) elem 4 | 5 | 6 | 7 | append_swap : Vect n elem -> Vect m elem -> Vect (m + n) elem 8 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part2/checkEq2.idr: -------------------------------------------------------------------------------- 1 | checkEqNat : (num1 : Nat) -> (num2 : Nat) -> Maybe (num1 = num2) 2 | checkEqNat Z Z = Just Refl 3 | checkEqNat (S Z) Z = Nothing 4 | checkEqNat Z (S Z) = Nothing 5 | checkEqNat (S a) (S b) = case checkEqNat a b of 6 | Nothing => Nothing 7 | Just Refl => Just Refl 8 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part2/checkEq4.idr: -------------------------------------------------------------------------------- 1 | checkEqNat : (num1 : Nat) -> (num2 : Nat) -> Dec (num1 = num2) 2 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part2/exactLength1.idr: -------------------------------------------------------------------------------- 1 | data Vect : Nat -> Type -> Type where 2 | Nil : Vect Z a 3 | (::) : a -> Vect k a -> Vect (S k) a 4 | 5 | %name Vect xs, ys, zs 6 | 7 | data EqNat : Nat -> Nat -> Type where 8 | Same : (x : Nat) -> EqNat x x 9 | 10 | sameS : (k : Nat) -> (j : Nat) -> (eq : EqNat k j) -> EqNat (S k) (S j) 11 | sameS p p (Same p) = Same (S p) 12 | 13 | 14 | checkEqNat : (num1 : Nat) -> (num2 : Nat) -> Maybe (EqNat num1 num2) 15 | checkEqNat Z Z = Just (Same Z) 16 | checkEqNat (S t) Z = Nothing 17 | checkEqNat Z (S t) = Nothing 18 | checkEqNat (S a) (S b) = case checkEqNat a b of 19 | Nothing => Nothing 20 | Just (Same p) => Just (Same (S p)) 21 | 22 | 23 | exactLength : {m:Nat} -> (len : Nat) -> (input : Vect m a) -> Maybe (Vect len a) 24 | exactLength {m=m} l v = case checkEqNat l m of 25 | Nothing => Nothing 26 | Just (Same p) => Just v 27 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part2/readvec0.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | import Data.Vect 4 | 5 | read_vect : IO (len ** Vect len String) 6 | read_vect = do x <- getLine 7 | if (x == "") 8 | then pure (_ ** []) 9 | else do (_ ** xs) <- read_vect 10 | pure (_ ** x :: xs) 11 | 12 | zipInputs : IO () 13 | zipInputs = do putStrLn "Enter first vector (blank line to end):" 14 | (len1 ** vec1) <- read_vect 15 | 16 | putStrLn "Enter second vector (blank line to end):" 17 | (len2 ** vec2) <- read_vect 18 | 19 | case exactLength len1 vec2 of 20 | Nothing => putStrLn "Vectors are different lengths" 21 | Just vec2' => printLn (zip vec1 vec2') 22 | 23 | main : IO () 24 | main = zipInputs 25 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part2/void3.idr: -------------------------------------------------------------------------------- 1 | twoplustwo_not_five : 2 + 2 = 5 -> Void 2 | twoplustwo_not_five = twoplustwo_not_five 3 | 4 | 5 | value_not_suc : (x : Nat) -> x = S x -> Void 6 | value_not_suc x Relf = value_not_suc (S x) Relf 7 | 8 | 9 | 10 | -- The following definitions are not total, so can't be accepted as proofs 11 | 12 | loop : Void 13 | loop = loop 14 | 15 | nohead : Void 16 | nohead = getHead [] 17 | where 18 | getHead : List Void -> Void 19 | getHead (x :: xs) = x 20 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Effects/Door1.idr: -------------------------------------------------------------------------------- 1 | module Door 2 | 3 | import Effects 4 | 5 | data DoorState = Closed | Open 6 | data DoorInfo : DoorState -> Type where 7 | DI : DoorInfo s 8 | 9 | data Door : Effect where 10 | OpenDoor : sig Door () (DoorInfo Closed) (DoorInfo Open) 11 | CloseDoor : sig Door () (DoorInfo Open) (DoorInfo Closed) 12 | Knock : sig Door () (DoorInfo Closed) 13 | 14 | DOOR : DoorState -> EFFECT 15 | DOOR t = MkEff (DoorInfo t) Door 16 | 17 | 18 | ------ 19 | openDoor : Eff () [DOOR Closed] [DOOR Open] 20 | openDoor = call OpenDoor 21 | 22 | closeDoor : Eff () [DOOR Open] [DOOR Closed] 23 | closeDoor = call CloseDoor 24 | 25 | knock : Eff () [DOOR Closed] 26 | knock = call Knock 27 | 28 | doorProg : Eff () [DOOR Closed] 29 | doorProg = do knock 30 | openDoor 31 | closeDoor 32 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Effects/Door2.idr: -------------------------------------------------------------------------------- 1 | module Door 2 | 3 | import Effects 4 | import Effect.StdIO 5 | 6 | data DoorState = Closed | Open 7 | 8 | data DoorInfo : DoorState -> Type where 9 | DI : DoorInfo s 10 | 11 | data Jam = Jammed | OK 12 | 13 | data Door : Effect where 14 | OpenDoor : sig Door Jam (DoorInfo Closed) 15 | (\jammed => DoorInfo (case jammed of 16 | Jammed => Closed 17 | OK => Open)) 18 | CloseDoor : sig Door () (DoorInfo Open) (DoorInfo Closed) 19 | Knock : sig Door () (DoorInfo Closed) 20 | 21 | DOOR : DoorState -> EFFECT 22 | DOOR t = MkEff (DoorInfo t) Door 23 | 24 | ------ 25 | openDoor : Eff Jam [DOOR Closed] 26 | (\jammed => [DOOR (case jammed of 27 | Jammed => Closed 28 | OK => Open)]) 29 | openDoor = call OpenDoor 30 | 31 | closeDoor : Eff () [DOOR Open] [DOOR Closed] 32 | closeDoor = call CloseDoor 33 | 34 | knock : Eff () [DOOR Closed] 35 | knock = call Knock 36 | 37 | ------ 38 | doorProg : Eff () [STDIO, DOOR Closed] 39 | doorProg = do knock 40 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Effects/Expr.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | import Effects 4 | import Effect.State 5 | import Effect.Exception 6 | import Effect.Random 7 | import Effect.StdIO 8 | 9 | data Expr = Var String 10 | | Val Integer 11 | | Add Expr Expr 12 | 13 | Env : Type 14 | Env = List (String, Integer) 15 | 16 | ExprProg : Type -> Type 17 | ExprProg t = Eff t [STDIO, EXCEPTION String, STATE Env] 18 | 19 | getRnd : Integer -> Eff Integer [RND] 20 | getRnd upper = do val <- rndInt 0 upper 21 | return val 22 | 23 | eval : Expr -> Eff Integer [STDIO, EXCEPTION String, STATE Env] 24 | eval (Var x) 25 | = case lookup x !get of 26 | Nothing => raise ("No such variable " ++ x) 27 | Just val => pure val 28 | eval (Val x) = pure x 29 | eval (Add l r) = do l' <- eval l 30 | r' <- eval r 31 | pure (l' + r') 32 | 33 | testExpr : Expr 34 | testExpr = Add (Add (Var "foo") (Val 42)) (Val 100) 35 | 36 | runEval : List (String, Integer) -> Expr -> IO Integer 37 | runEval args expr = run (eval' expr) 38 | where eval' : Expr -> ExprProg Integer 39 | eval' e = do put args 40 | eval e 41 | 42 | main : IO () 43 | main = do putStr "Number: " 44 | x <- getLine 45 | val <- runEval [("foo", cast x)] testExpr 46 | putStrLn $ "Answer: " ++ show val 47 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Effects/Queens.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | import Effects 4 | import Select 5 | 6 | no_attack : (Int, Int) -> (Int, Int) -> Bool 7 | no_attack (x, y) (x', y') 8 | = x /= x' && y /= y' && abs (x - x') /= abs (y - y') 9 | 10 | rowsIn : Int -> List (Int, Int) -> List Int 11 | rowsIn col qs = [ x | x <- [1..8], all (no_attack (x, col)) qs ] 12 | 13 | addQueens : Int -> List (Int, Int) -> { [SELECT] } Eff (List (Int, Int)) 14 | addQueens 0 qs = return qs 15 | addQueens col qs = do row <- select (rowsIn col qs) 16 | addQueens (col - 1) ((row, col) :: qs) 17 | 18 | getQueens : List (List (Int, Int)) 19 | getQueens = run (addQueens 8 []) 20 | 21 | main : IO () 22 | main = do let qs = getQueens 23 | -- putStrLn ("Solution:\n" ++ show qs) 24 | 25 | let num = the Integer (cast (length qs)) 26 | putStrLn (show num ++ " solutions:\n" ++ showAll qs) 27 | where showAll [] = "" 28 | showAll (x :: xs) = show x ++ "\n" ++ showAll xs 29 | 30 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Effects/Select.idr: -------------------------------------------------------------------------------- 1 | module Select 2 | 3 | import Effects 4 | 5 | data Selection : Effect where 6 | Select : List a -> sig Selection a () 7 | 8 | instance Handler Selection Maybe where 9 | handle _ (Select xs) k = tryAll xs where 10 | tryAll [] = Nothing 11 | tryAll (x :: xs) = case k x () of 12 | Nothing => tryAll xs 13 | Just v => Just v 14 | 15 | instance Handler Selection List where 16 | handle r (Select xs) k = concatMap (\x => k x r) xs 17 | 18 | SELECT : EFFECT 19 | SELECT = MkEff () Selection 20 | 21 | select : List a -> Eff a [SELECT] 22 | select xs = call $ Select xs 23 | 24 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Effects/effects_demos.ipkg: -------------------------------------------------------------------------------- 1 | package demos 2 | 3 | modules = Door1, Door2, Expr, Queens, Select 4 | opts = "-p effects" 5 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Effects/hello.idr: -------------------------------------------------------------------------------- 1 | import Effects 2 | import Effect.StdIO 3 | import Effect.Exception 4 | 5 | hello : Eff () [STDIO] 6 | hello = do putStr "What is your name? " 7 | x <- getStr 8 | putStrLn ("Hello " ++ x) 9 | 10 | main : IO () 11 | main = run hello 12 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Hangman/VectMissing.idr: -------------------------------------------------------------------------------- 1 | module VectMissing 2 | 3 | import Data.Fin 4 | import Data.Vect 5 | 6 | export 7 | shrink : (xs : Vect (S n) a) -> Elem x xs -> Vect n a 8 | shrink (x :: ys) Here = ys 9 | shrink (y :: []) (There p) = absurd p 10 | shrink (y :: (x :: xs)) (There p) = y :: shrink (x :: xs) p 11 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Hangman/hangman.ipkg: -------------------------------------------------------------------------------- 1 | package hangman 2 | 3 | modules = VectMissing, hangman 4 | opts = "-p effects" 5 | 6 | executable = hangman 7 | main = hangman 8 | 9 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/IO/hello.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | main : IO () 4 | main = do 5 | putStr "Enter your name: " 6 | x <- getLine 7 | putStrLn ("Hello " ++ x ++ "!") 8 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/Aliens.idr: -------------------------------------------------------------------------------- 1 | module Aliens 2 | 3 | import Effect.SDL 4 | import Effects 5 | 6 | %access public export 7 | 8 | record Alien where 9 | constructor MkAlien 10 | position : (Int, Int) 11 | xmovement : Int 12 | xstep : Int 13 | ystep : Int 14 | 15 | startAliens : List Alien 16 | startAliens = alienRow (-1) 100 ++ 17 | alienRow 1 150 ++ alienRow (-1) 200 18 | where 19 | alienRow : Int -> Int -> List Alien 20 | alienRow mv y = map (\x => MkAlien (x*60, y) mv 30 15) [1..10] 21 | 22 | move : List (Int, Int) -> -- bullet position 23 | List Alien -> List Alien 24 | move bs as = map moveAlien as 25 | where moveAlien a = let xstep' = if (xstep a == 0) then 30 else xstep a - 1 in 26 | let ystep' = if (ystep a == 0) then 15 else ystep a - 1 in 27 | let (x, y) = position a in 28 | let y' = if (ystep a == 0) then y+1 else y in 29 | let xmovement' = if xstep a == 0 then -(xmovement a) 30 | else xmovement a in 31 | record { position = (x + xmovement a, y'), 32 | xmovement = xmovement', 33 | xstep = xstep', 34 | ystep = ystep' } a 35 | 36 | -- if any pair of bullet/alien collide, remove both 37 | checkHit : List (Int, Int) -> List Alien -> (List (Int, Int), List Alien) 38 | checkHit bs as = checkAll bs as [] [] 39 | where testHit : (Int, Int) -> Alien -> Bool 40 | testHit (x, y) a 41 | = let (ax, ay) = position a in 42 | (abs (x - ax) < 20 && abs (y - ay) < 15) -- hit! 43 | 44 | checkAll : List (Int, Int) -> List Alien -> List Alien -> List (Int, Int) -> 45 | (List (Int, Int), List Alien) 46 | checkAll (b :: bs) (a :: as) asAcc bsAcc 47 | = if testHit b a 48 | then checkAll bs as asAcc bsAcc 49 | else checkAll (b :: bs) as (a :: asAcc) bsAcc 50 | checkAll (b :: bs) [] asAcc bsAcc 51 | = checkAll bs asAcc [] (b :: bsAcc) 52 | checkAll [] as asAcc bsAcc = (bsAcc, as ++ asAcc) 53 | 54 | drawAliens : List Alien -> Eff () [SDL_ON] 55 | drawAliens [] = return () 56 | drawAliens (a :: as) = do let (x, y) = Alien.position a 57 | drawAlien x y 58 | drawAliens as 59 | where drawAlien : Int -> Int -> Eff () [SDL_ON] 60 | drawAlien x y = do ellipse green x y 20 16 61 | ellipse red (x-8) (y-6) 3 3 62 | ellipse red (x-8) (y+6) 3 3 63 | rectangle red (x-2) (y-3) 16 4 64 | rectangle red (x-2) (y+3) 16 4 65 | 66 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/Gamestate.idr: -------------------------------------------------------------------------------- 1 | module Gamestate 2 | 3 | import Effects 4 | import Effect.State 5 | import Effect.SDL 6 | import Effect.StdIO 7 | 8 | import Aliens 9 | import Rnd 10 | 11 | %access public export 12 | 13 | record Gamestate where 14 | constructor MkGamestate 15 | position : (Int, Int) 16 | xmovement : Int 17 | ymovement : Int 18 | bullets : List (Int, Int) 19 | bombs : List (Int, Int) 20 | aliens : List Alien 21 | 22 | initState : Gamestate 23 | initState = MkGamestate (320,400) 0 0 [] [] startAliens 24 | 25 | --------- 26 | -- Game state effect needs access to a random number generator 27 | 28 | GS : Type -> Type 29 | GS t = Eff t [Gamestate ::: STATE Gamestate, RND] 30 | 31 | moveBullets : Gamestate -> Gamestate 32 | moveBullets gs = let bullets' = movebs (bullets gs) in 33 | record { bullets = bullets' } gs 34 | where movebs [] = [] 35 | movebs ((x, y) :: bs) 36 | = if y < 0 then movebs bs 37 | else ((x, y-5) :: movebs bs) 38 | 39 | moveBombs : Gamestate -> Gamestate 40 | moveBombs gs = let bombs' = movebs (bombs gs) in 41 | record { bombs = bombs' } gs 42 | where movebs [] = [] 43 | movebs ((x, y) :: bs) 44 | = if y > 480 then movebs bs 45 | else ((x, y+5) :: movebs bs) 46 | 47 | moveAliens : Gamestate -> Gamestate 48 | moveAliens gs = record { aliens = move (bullets gs) (aliens gs) } gs 49 | 50 | removeHit : Gamestate -> Gamestate 51 | removeHit gs = let bs = bullets gs in 52 | let as = aliens gs in 53 | let (bs', as') = checkHit bs as in 54 | record { bullets = bs', aliens = as' } gs 55 | 56 | drawBullets : List (Int, Int) -> { [SDL_ON] } Eff () 57 | drawBullets [] = return () 58 | drawBullets ((x, y) :: bs) = do rectangle red (x-1) (y-4) 2 8 59 | drawBullets bs 60 | 61 | drawBombs : List (Int, Int) -> { [SDL_ON] } Eff () 62 | drawBombs [] = return () 63 | drawBombs ((x, y) :: bs) = do rectangle yellow (x-1) (y-4) 2 8 64 | drawBombs bs 65 | 66 | randomDropBomb : GS () 67 | randomDropBomb = randomDrop (map (Alien.position) (aliens !(Gamestate :- get))) 68 | where 69 | randomDrop : List (Int, Int) -> GS () 70 | randomDrop [] = return () 71 | randomDrop ((x, y) :: as) 72 | = do if (!(rndInt 1 3000) == 100) 73 | then (do s <- Gamestate :- get 74 | let bs = bombs s 75 | Gamestate :- put (record { bombs = (x, y+10) :: bs } s)) 76 | else randomDrop as 77 | 78 | --------- 79 | updateGamestate : GS () 80 | updateGamestate = do gs <- Gamestate :- get 81 | let (x, y) = Gamestate.position gs 82 | let (x', y') = (bounds 10 630 (x + xmovement gs), 83 | bounds 380 460 (y + ymovement gs)) 84 | 85 | let gs' = record { position = (x', y') } gs 86 | let gs'' = moveAliens (moveBombs (moveBullets gs')) 87 | Gamestate :- put (removeHit gs'') 88 | randomDropBomb 89 | 90 | where bounds : Int -> Int -> Int -> Int 91 | bounds low high v = if v < low then low 92 | else if v > high then high 93 | else v 94 | 95 | getPos : GS (Int, Int) 96 | getPos = do s <- Gamestate :- get 97 | return (position s) 98 | 99 | xmove : Int -> GS () 100 | xmove x = do s <- Gamestate :- get 101 | Gamestate :- put (record { xmovement = x } s) 102 | 103 | ymove : Int -> GS () 104 | ymove x = do s <- Gamestate :- get 105 | Gamestate :- put (record { ymovement = x } s) 106 | 107 | addBullet : GS () 108 | addBullet = do s <- Gamestate :- get 109 | let bs = bullets s 110 | (x, y) <- getPos 111 | Gamestate :- put (record { bullets = (x, y-10) :: bs } s) 112 | 113 | -- Deal with keypresses from SDL 114 | process : Maybe Event -> GS Bool 115 | process (Just AppQuit) = return False 116 | process (Just (KeyDown KeyLeftArrow)) = do xmove (-2); return True 117 | process (Just (KeyUp KeyLeftArrow)) = do xmove 0; return True 118 | process (Just (KeyDown KeyRightArrow)) = do xmove 2; return True 119 | process (Just (KeyUp KeyRightArrow)) = do xmove 0; return True 120 | process (Just (KeyDown KeyUpArrow)) = do ymove (-2); return True 121 | process (Just (KeyUp KeyUpArrow)) = do ymove 0; return True 122 | process (Just (KeyDown KeyDownArrow)) = do ymove 2; return True 123 | process (Just (KeyUp KeyDownArrow)) = do ymove 0; return True 124 | process (Just (KeyDown KeySpace)) = do addBullet; return True 125 | process _ = return True 126 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/Main.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | import Effects 4 | 5 | import Effect.SDL 6 | import Effect.State 7 | import Effect.StdIO 8 | 9 | import Rnd 10 | import Aliens 11 | import Starfield 12 | import Gamestate 13 | 14 | data Frames : Type where -- empty type, just for labelling 15 | 16 | ------- 17 | -- SDL effect is parameterised by an underyling 'surface' resource which 18 | -- only exists when initialised. 19 | 20 | -- The program supports SDL, carries state, and supports random number 21 | -- generation and console I/O 22 | 23 | Prog : Type -> Type -> Type 24 | Prog i t = Eff t [SDL i, 25 | Frames ::: STATE Integer, 26 | Gamestate ::: STATE Gamestate, 27 | Starfield ::: STATE (List (Int, Int)), 28 | RND, 29 | STDIO] 30 | 31 | -- Convenient shorthand for initialised SDL 32 | Running : Type -> Type 33 | Running t = Prog SDLSurface t 34 | 35 | ------- 36 | emain : Prog () () 37 | emain = do putStrLn "Initialising" 38 | putStrLn "..." 39 | initialise 640 480 40 | putStrLn "Initialised" 41 | initStarfield [] 200 42 | eventLoop 43 | quit 44 | where 45 | draw : Running () 46 | draw = do rectangle black 0 0 640 480 47 | drawStarfield !(Starfield :- get) 48 | gs <- Gamestate :- get 49 | drawBullets (bullets gs) 50 | drawBombs (bombs gs) 51 | drawAliens (aliens gs) 52 | p <- getPos 53 | let (x, y) = p 54 | rectangle blue (x-10) (y-10) 20 20 55 | rectangle blue (x-1) (y-20) 2 10 56 | flip 57 | 58 | -- update the world state by moving the ellipse to a new position 59 | -- and scrolling the starfield. Also print the number of frames 60 | -- drawn so far every so often. 61 | 62 | updateWorld : Running () 63 | updateWorld = do f <- Frames :- get 64 | Frames :- put (f + 1) 65 | when ((f `mod` 100) == 0) (putStrLn (show f)) 66 | updateStarfield 67 | updateGamestate 68 | 69 | ------- 70 | -- Event loop simply has to draw the current state, update the 71 | -- state according to how the ellipse is moving, then process 72 | -- any incoming events 73 | 74 | eventLoop : Running () 75 | eventLoop = do draw 76 | updateWorld 77 | when !(process !poll) eventLoop 78 | 79 | 80 | main : IO () 81 | main = runInit [(), Frames := 0, 82 | Gamestate := initState, 83 | Starfield := List.Nil, 84 | 1234567890, 85 | ()] emain 86 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/Rnd.idr: -------------------------------------------------------------------------------- 1 | module Rnd 2 | 3 | import Effects 4 | 5 | %access public export 6 | 7 | data Random : Effect where 8 | GetRandom : Random Int Int (\v => Int) 9 | 10 | Handler Random m where 11 | handle seed GetRandom k 12 | = let seed' = assert_total ((1664525 * seed + 1013904223) `prim__sremInt` (pow 2 32)) in 13 | k seed' seed' 14 | 15 | RND : EFFECT 16 | RND = MkEff Int Random 17 | 18 | rndInt : Int -> Int -> Eff Int [RND] 19 | rndInt lower upper = do v <- call GetRandom 20 | return (abs (v `prim__sremInt` (upper - lower)) + lower) 21 | 22 | 23 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/SDL-idris/Makefile: -------------------------------------------------------------------------------- 1 | install: 2 | idris --install sdl.ipkg 3 | 4 | clean: 5 | idris --clean sdl.ipkg 6 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/SDL-idris/README.md: -------------------------------------------------------------------------------- 1 | SDL-idris 2 | ========= 3 | 4 | SDL bindings package for idris 5 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/SDL-idris/sdl.ipkg: -------------------------------------------------------------------------------- 1 | package sdl 2 | 3 | sourcedir = src 4 | modules = Graphics.SDL, Graphics.Config, Effect.SDL 5 | opts = "-p effects" 6 | 7 | makefile = MakefileSDLC 8 | 9 | objs = sdlrun.o, sdlrun.h 10 | libs = SDL, SDL_gfx 11 | 12 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/SDL-idris/src/Effect/SDL.idr: -------------------------------------------------------------------------------- 1 | module Effect.SDL 2 | 3 | import Effects 4 | import public Graphics.SDL 5 | 6 | %access public export 7 | 8 | Srf : Type 9 | Srf = SDLSurface 10 | 11 | data Colour = MkCol Int Int Int Int 12 | 13 | black : Colour 14 | black = MkCol 0 0 0 255 15 | 16 | white : Colour 17 | white = MkCol 255 255 255 255 18 | 19 | red : Colour 20 | red = MkCol 255 0 0 255 21 | 22 | green : Colour 23 | green = MkCol 0 255 0 255 24 | 25 | blue : Colour 26 | blue = MkCol 0 0 255 255 27 | 28 | yellow : Colour 29 | yellow = MkCol 255 255 0 255 30 | 31 | cyan : Colour 32 | cyan = MkCol 0 255 255 255 33 | 34 | magenta : Colour 35 | magenta = MkCol 255 0 255 255 36 | 37 | data Sdl : Effect where 38 | Initialise : Int -> Int -> Sdl () () (\v => Srf) 39 | Quit : Sdl () Srf (\v => ()) 40 | Flip : Sdl () Srf (\v => Srf) 41 | Poll : Sdl (Maybe Event) a (\v => a) 42 | 43 | WithSurface : (Srf -> IO a) -> Sdl a Srf (\v => Srf) 44 | 45 | Handler Sdl IO where 46 | handle () (Initialise x y) k = do srf <- startSDL x y; k () srf 47 | handle s Quit k = do endSDL; k () () 48 | 49 | handle s Flip k = do flipBuffers s; k () s 50 | handle s Poll k = do x <- pollEvent; k x s 51 | handle s (WithSurface f) k = do r <- f s; k r s 52 | 53 | public export 54 | SDL : Type -> EFFECT 55 | SDL res = MkEff res Sdl 56 | 57 | public export 58 | SDL_ON : EFFECT 59 | SDL_ON = SDL SDLSurface 60 | 61 | initialise : Int -> Int -> { [SDL ()] ==> [SDL_ON] } Eff () 62 | initialise x y = call $ Initialise x y 63 | 64 | quit : { [SDL_ON] ==> [SDL ()] } Eff () 65 | quit = call Quit 66 | 67 | flip : { [SDL_ON] } Eff () 68 | flip = call Flip 69 | 70 | poll : { [SDL_ON] } Eff (Maybe Event) 71 | poll = call Poll 72 | 73 | getSurface : { [SDL_ON] } Eff SDLSurface 74 | getSurface = call $ WithSurface (\s => return s) 75 | 76 | rectangle : Colour -> Int -> Int -> Int -> Int -> { [SDL_ON] } Eff () 77 | rectangle (MkCol r g b a) x y w h 78 | = call $ WithSurface (\s => filledRect s x y w h r g b a) 79 | 80 | ellipse : Colour -> Int -> Int -> Int -> Int -> { [SDL_ON] } Eff () 81 | ellipse (MkCol r g b a) x y rx ry 82 | = call $ WithSurface (\s => filledEllipse s x y rx ry r g b a) 83 | 84 | line : Colour -> Int -> Int -> Int -> Int -> { [SDL_ON] } Eff () 85 | line (MkCol r g b a) x y ex ey 86 | = call $ WithSurface (\s => drawLine s x y ex ey r g b a) 87 | 88 | 89 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/SDL-idris/src/Graphics/Config.idr: -------------------------------------------------------------------------------- 1 | %flag C "-L/usr/local/lib -lSDLmain -lSDL -Wl,-framework,Cocoa" 2 | %flag C "-I/usr/local/include/SDL -D_GNU_SOURCE=1 -D_THREAD_SAFE" 3 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/SDL-idris/src/MakefileSDLC: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = `idris --include` `sdl-config --cflags` 3 | 4 | sdlrun.o: config sdlrun.c sdlrun.h 5 | 6 | config: .PHONY 7 | echo "%flag C \"`sdl-config --libs`\"" > Graphics/Config.idr 8 | echo "%flag C \"`sdl-config --cflags`\"" >> Graphics/Config.idr 9 | 10 | clean: .PHONY 11 | rm sdlrun.o 12 | 13 | .PHONY: 14 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/SDL-idris/src/sdlrun.h: -------------------------------------------------------------------------------- 1 | #ifndef __SDLRUN_H 2 | #define __SDLRUN_H 3 | 4 | #include 5 | 6 | // Start SDL, open a window with dimensions (x,y) 7 | void* startSDL(int x, int y); 8 | 9 | // Drawing primitives 10 | void filledRect(void *s, 11 | int x, int y, int w, int h, 12 | int r, int g, int b, int a); 13 | void flipBuffers(void* s_in); 14 | void filledEllipse(void* s_in, 15 | int x, int y, int rx, int ry, 16 | int r, int g, int b, int a); 17 | void drawLine(void* s_in, 18 | int x, int y, int ex, int ey, 19 | int r, int g, int b, int a); 20 | 21 | // Events 22 | void* pollEvent(VM* vm); // builds an Idris value 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/Starfield.idr: -------------------------------------------------------------------------------- 1 | module Starfield 2 | 3 | -- Background starfield effect 4 | 5 | import Effects 6 | import Effect.SDL 7 | import Effect.StdIO 8 | import Effect.State 9 | 10 | import Rnd 11 | 12 | %access public export 13 | 14 | data Starfield : Type where -- for labelling state 15 | 16 | StarEff : Type -> Type 17 | StarEff t = Eff t [Starfield ::: STATE (List (Int, Int)), RND] 18 | 19 | initStarfield : List (Int, Int) -> Nat -> StarEff () 20 | initStarfield acc Z = Starfield :- put acc 21 | initStarfield acc n 22 | = do x <- rndInt 0 639 23 | y <- rndInt 0 479 24 | initStarfield ((x, y) :: acc) (minus n 1) 25 | 26 | updateStarfield : StarEff () 27 | updateStarfield = do xs <- Starfield :- get 28 | xs' <- upd [] xs 29 | Starfield :- put xs' 30 | where 31 | upd : List (Int, Int) -> List (Int, Int) -> { [RND] } Eff (List (Int, Int)) 32 | upd acc [] = return acc 33 | upd acc ((x, y) :: xs) 34 | = if (y > 479) then do 35 | x <- rndInt 0 639 36 | upd ((x, 0) :: acc) xs 37 | else 38 | upd ((x, y+1) :: acc) xs 39 | 40 | drawStarfield : List (Int, Int) -> { [SDL_ON] } Eff () 41 | drawStarfield [] = return () 42 | drawStarfield ((x, y) :: xs) = do line white x y x y 43 | drawStarfield xs 44 | 45 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part3/Invaders/invaders.ipkg: -------------------------------------------------------------------------------- 1 | package invaders 2 | 3 | modules = Starfield, Gamestate, Aliens, Rnd, Main 4 | opts = "-p effects -p sdl --warnreach" 5 | 6 | executable = invaders 7 | main = Main 8 | 9 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part4/Views/describe_list.idr: -------------------------------------------------------------------------------- 1 | data ListLast : List a -> Type where 2 | Empty : ListLast [] 3 | NonEmpty : (xs : List a) -> (x : a) -> ListLast (xs ++ [x]) 4 | 5 | listLast : (xs : List a) -> ListLast xs 6 | listLast [] = Empty 7 | listLast (x :: xs) = case listLast xs of 8 | Empty => NonEmpty [] x 9 | NonEmpty xs y => NonEmpty (x :: xs) y 10 | 11 | describe_help : (input : List Int) -> ListLast input -> String 12 | describe_help [] Empty = "Empty" 13 | describe_help (xs ++ [x]) (NonEmpty xs x) 14 | = "Non-empty, initial portion = " ++ show xs 15 | 16 | describe_list_end : List Int -> String 17 | describe_list_end xs = describe_help xs (listLast xs) 18 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part4/Views/dlfail.idr: -------------------------------------------------------------------------------- 1 | describe_list_end : List Int -> String 2 | describe_list_end [] = "Empty" 3 | describe_list_end (xs ++ [x]) = "Non-empty, initial portion = " ++ show xs 4 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part4/Views/merge_sort.idr: -------------------------------------------------------------------------------- 1 | import Debug.Trace 2 | 3 | data SplitList : List a -> Type where 4 | SplitNil : SplitList [] 5 | SplitOne : SplitList [x] 6 | SplitPair : (lefts : List a) -> (rights : List a) -> 7 | SplitList (lefts ++ rights) 8 | 9 | total 10 | splitList : (xs : List a) -> SplitList xs 11 | splitList xs = splitListHelp xs xs 12 | where 13 | splitListHelp : (counter : List a) -> (xs : List a) -> SplitList xs 14 | splitListHelp _ [] = SplitNil 15 | splitListHelp _ [x] = SplitOne 16 | splitListHelp (_ :: _ :: ys) (x :: xs) 17 | = case splitListHelp ys xs of 18 | SplitNil => SplitOne 19 | SplitOne {x=y} => SplitPair [x] [y] 20 | SplitPair lefts rights => SplitPair (x :: lefts) rights 21 | splitListHelp _ xs = SplitPair [] xs 22 | 23 | merge_sort : Ord a => List a -> List a 24 | 25 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part4/Views/merge_sort_view.idr: -------------------------------------------------------------------------------- 1 | import Data.List.Views 2 | 3 | merge_sort : Ord a => List a -> List a 4 | merge_sort xs with (splitRec xs) 5 | merge_sort xs | with_pat = ?merge_sort_rhs 6 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part4/Views/reverse.idr: -------------------------------------------------------------------------------- 1 | data ListLast : List a -> Type where 2 | Empty : ListLast [] 3 | NonEmpty : (xs : List a) -> (x : a) -> ListLast (xs ++ [x]) 4 | 5 | listLast : (xs : List a) -> ListLast xs 6 | listLast [] = Empty 7 | listLast (x :: xs) = case listLast xs of 8 | Empty => NonEmpty [] x 9 | NonEmpty xs y => NonEmpty (x :: xs) y 10 | 11 | my_reverse : List a -> List a 12 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part4/Views/reverse_snoc.idr: -------------------------------------------------------------------------------- 1 | data SnocList ty = Empty | Snoc (SnocList ty) ty 2 | 3 | reverse_snoc : SnocList ty -> List ty 4 | reverse_snoc Empty = [] 5 | reverse_snoc (Snoc xs x) = x :: reverse_snoc xs 6 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part4/Views/snoclist.idr: -------------------------------------------------------------------------------- 1 | data SnocList : List a -> Type where 2 | Empty : SnocList [] 3 | Snoc : (rec : SnocList xs) -> SnocList (xs ++ [x]) 4 | 5 | snocListHelp : SnocList input -> (xs : List a) -> SnocList (input ++ xs) 6 | snocListHelp {input} snoc [] = rewrite appendNilRightNeutral input in snoc 7 | snocListHelp {input} snoc (x :: xs) 8 | = rewrite appendAssociative input [x] xs in snocListHelp (Snoc snoc) xs 9 | 10 | snocList : (xs : List a) -> SnocList xs 11 | snocList xs = snocListHelp Empty xs 12 | 13 | my_reverse_help : (input : List a) -> SnocList input -> List a 14 | my_reverse_help [] Empty = [] 15 | my_reverse_help (xs ++ [x]) (Snoc rec) = x :: my_reverse_help xs rec 16 | 17 | my_reverse1 : List a -> List a 18 | my_reverse1 input = my_reverse_help input (snocList input) 19 | 20 | my_reverse : List a -> List a 21 | 22 | 23 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part4/infIO-stream3.idr: -------------------------------------------------------------------------------- 1 | %default total 2 | 3 | data InfIO : Type -> Type where 4 | Do : IO a -> (a -> Inf (InfIO b)) -> InfIO b 5 | 6 | echo_name : InfIO () 7 | echo_name = Do (putStr "Enter your name: ") $ \_ => 8 | Do getLine $ \name => 9 | Do (putStrLn ("Hello " ++ name)) $ \_ => 10 | echo_name 11 | 12 | data Fuel = Dry | More (Lazy Fuel) 13 | 14 | tank : Nat -> Fuel 15 | tank Z = Dry 16 | tank (S k) = More (tank k) 17 | 18 | run : Fuel -> InfIO a -> IO (Maybe a) 19 | run (More fuel) (Do c f) = do res <- c 20 | run fuel (f res) 21 | run Dry p = pure Nothing 22 | 23 | partial 24 | forever : Fuel 25 | forever = More forever 26 | 27 | partial 28 | main : IO () 29 | main = do run (tank 10) echo_name 30 | pure () 31 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part4/rndstream2.idr: -------------------------------------------------------------------------------- 1 | import Data.Primitives.Views 2 | 3 | randoms : Int -> Stream Int 4 | randoms seed = let seed' = 1664525 * seed + 1013904223 in 5 | (seed' `div` 64) :: randoms seed' 6 | 7 | data Face = Heads | Tails 8 | 9 | Eq Face where 10 | (==) Heads Heads = True 11 | (==) Tails Tails = True 12 | (==) _ _ = False 13 | 14 | total 15 | getFace : Int -> Face 16 | getFace x with (divides x 2) 17 | getFace ((2 * div) + rem) | (DivBy prf) 18 | = case rem of 19 | 0 => Heads 20 | _ => Tails 21 | 22 | coinFlips : Nat -> Stream Int -> List Face 23 | coinFlips k rnds = map getFace (take k rnds) 24 | 25 | -------------------------------------------------------------------------------- /idris/Kats-Code/Part4/streams1.idr: -------------------------------------------------------------------------------- 1 | ones : Stream Int 2 | ones = 1 :: ones 3 | 4 | countFrom : Num numType => numType -> Stream numType 5 | countFrom x = x :: countFrom (x + 1) 6 | 7 | -------------------------------------------------------------------------------- /idris/hello.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | isSingleton : Bool -> Type 4 | isSingleton True = Nat 5 | isSingleton False = List Nat 6 | 7 | main : IO () 8 | main = putStrLn "hello world" 9 | -------------------------------------------------------------------------------- /idris/sort/l1.idr: -------------------------------------------------------------------------------- 1 | module l1 2 | 3 | data UL : Nat -> UniqueType -> UniqueType where 4 | Nil : {a:UniqueType} -> UL Z a 5 | (::) : {a:UniqueType} -> a -> UL k a -> UL (S k) a 6 | 7 | 8 | data UNat : UniqueType where 9 | UZ : UNat 10 | US : UNat -> UNat 11 | 12 | usort : UL n UNat -> UL n UNat 13 | usort Nil = Nil 14 | usort (x :: xs) = insert x (usort xs) where 15 | mutual 16 | go : Borrowed UNat -> Borrowed UNat -> UNat -> UNat -> UL n UNat -> UL (S (S n)) UNat 17 | go UZ _ a b bs = a :: b :: bs 18 | go _ UZ a b bs = b :: (insert a bs) 19 | go (US n) (US k) a b bs = go n k a b bs 20 | insert : UNat -> UL n UNat -> UL (S n) UNat 21 | insert a Nil = a :: Nil 22 | insert a (b :: bs) = go (lend a) (lend b) a b bs 23 | -------------------------------------------------------------------------------- /inotify/README.markdown: -------------------------------------------------------------------------------- 1 | A simple script that notifies changes in file and run `make` 2 | if there was a change. 3 | -------------------------------------------------------------------------------- /inotify/ion.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import System.INotify 4 | import System.Environment 5 | import System.Process 6 | import System.IO 7 | import Control.Concurrent 8 | import Control.Monad 9 | 10 | main = 11 | withINotify $ \inot -> do 12 | (f:_) <- getArgs 13 | x <- addWatch inot [Modify] f (const $ go inot f) 14 | hClose =<< openFile "iot.handle" WriteMode 15 | e <- newEmptyMVar 16 | addWatch inot [Delete] "iot.handle" (const $ putMVar e ()) 17 | takeMVar e 18 | where 19 | go inot f = do 20 | putStrLn "on" 21 | void . waitForProcess =<< runCommand "make" 22 | addWatch inot [Modify] f (const $ go inot f) 23 | putStrLn "off" 24 | 25 | -------------------------------------------------------------------------------- /iterative/examples1/conduit-1.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE BangPatterns #-} 2 | import Data.Conduit 3 | import qualified Data.Conduit.List as CL 4 | import qualified Data.Conduit.Binary as CB 5 | import Control.Monad.Trans.Resource 6 | import System.Environment 7 | 8 | numLines :: Monad m => Sink a m Int 9 | numLines = CL.fold go 0 where 10 | go !x _ = x+1 11 | 12 | main = do 13 | (f:_) <- getArgs 14 | print =<< (runResourceT $ CB.sourceFile f $$ CB.lines =$ numLines) 15 | -------------------------------------------------------------------------------- /iterative/examples1/iteratee-1.hs: -------------------------------------------------------------------------------- 1 | -- Derived from John Lato examples: 2 | -- https://github.com/JohnLato/iteratee/blob/master/Examples/word.hs 3 | {-# LANGUAGE BangPatterns #-} 4 | import Data.Iteratee 5 | import qualified Data.Iteratee as I 6 | import qualified Data.ByteString.Char8 as BC 7 | 8 | import Data.Char (ord) 9 | import Data.ListLike as LL 10 | import System.Environment (getArgs) 11 | 12 | -- | An efficient numLines using the foldl' iteratee. 13 | -- Rather than converting a stream, this simply counts newline characters. 14 | numLines :: Monad m => I.Iteratee BC.ByteString m Int 15 | numLines = I.foldl' step 0 16 | where 17 | step !acc el = if el == (fromIntegral $ ord '\n') then acc + 1 else acc 18 | 19 | main = do 20 | (fname:_) <- getArgs 21 | print =<< fileDriverVBuf 65536 numLines fname 22 | -------------------------------------------------------------------------------- /iterative/examples1/iteratee-2.hs: -------------------------------------------------------------------------------- 1 | -- Derived from John Lato examples: 2 | -- https://github.com/JohnLato/iteratee/blob/master/Examples/word.hs 3 | {-# LANGUAGE BangPatterns #-} 4 | import Data.Iteratee 5 | import qualified Data.Iteratee as I 6 | import qualified Data.Iteratee.IO as I 7 | import qualified Data.ByteString.Char8 as BC 8 | 9 | import Data.Char (ord) 10 | import Data.ListLike as LL 11 | import System.Environment (getArgs) 12 | 13 | -- | An efficient numLines using the foldl' iteratee. 14 | -- Rather than converting a stream, this simply counts newline characters. 15 | numLines :: Monad m => I.Iteratee BC.ByteString m Int 16 | numLines = I.foldl' step 0 17 | where 18 | step !acc el = if el == (fromIntegral $ ord '\n') then acc + 1 else acc 19 | 20 | main = do 21 | (fname:_) <- getArgs 22 | 23 | print =<< run =<< (I.enumFile 65536 fname >>> I.enumPure1Chunk "test") numLines) 24 | -------------------------------------------------------------------------------- /iterative/examples1/iteratee-3.hs: -------------------------------------------------------------------------------- 1 | -- Derived from John Lato examples: 2 | -- https://github.com/JohnLato/iteratee/blob/master/Examples/word.hs 3 | {-# LANGUAGE BangPatterns #-} 4 | import Data.Iteratee 5 | import qualified Data.Iteratee as I 6 | import qualified Data.ByteString.Char8 as BC 7 | 8 | import Data.Char (ord) 9 | import Data.ListLike as LL 10 | import System.Environment (getArgs) 11 | 12 | -- | An iteratee to calculate the number of characters in a stream. 13 | -- Very basic, assumes ASCII, not particularly efficient. 14 | numChars :: (Monad m, ListLike s el) => I.Iteratee s m Int 15 | numChars = I.length 16 | 17 | -- | An efficient numLines using the foldl' iteratee. 18 | -- Rather than converting a stream, this simply counts newline characters. 19 | numLines :: Monad m => I.Iteratee BC.ByteString m Int 20 | numLines = I.foldl' step 0 21 | where 22 | step !acc el = if el == (fromIntegral $ ord '\n') then acc + 1 else acc 23 | 24 | main = do 25 | (fname:_) <- getArgs 26 | print =<< fileDriverVBuf 65536 (numLines `I.zip` numChars) fname 27 | -------------------------------------------------------------------------------- /iterative/examples1/machines-1.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE Rank2Types #-} 2 | import Control.Monad.IO.Class 3 | import Control.Monad.Trans 4 | import Control.Monad.Trans.Resource 5 | import Data.Machine 6 | import System.IO 7 | 8 | import Control.Monad ( unless ) 9 | import System.Environment ( getArgs ) 10 | 11 | lineSource :: FilePath -> SourceT (ResourceT IO) String 12 | lineSource fp = construct $ do 13 | hdl <- fmap snd $ lift $ allocate (openFile fp ReadMode) hClose 14 | go hdl 15 | where 16 | go h = do c <- liftIO $ hIsEOF h 17 | unless c $ do 18 | l <- liftIO $ hGetLine h 19 | yield l 20 | go h 21 | 22 | numLines :: Monad m => MachineT m (Is a) Int 23 | numLines = fold step (0::Int) where 24 | step s _ = (s+1) 25 | 26 | main :: IO () 27 | main = do 28 | (f: _) <- getArgs 29 | print . head =<< runResourceT (runT (lineSource f ~> numLines)) 30 | -------------------------------------------------------------------------------- /iterative/examples1/machines-2.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE Rank2Types #-} 2 | import Control.Monad.IO.Class 3 | import Control.Monad.Trans 4 | import Control.Monad.Trans.Resource 5 | import Data.Machine 6 | import System.IO 7 | 8 | import Control.Monad ( unless ) 9 | import System.Environment ( getArgs ) 10 | import Control.Monad.Managed 11 | 12 | lineSource :: FilePath -> SourceT (ResourceT IO) String 13 | lineSource fp = construct $ do 14 | hdl <- fmap snd $ lift $ allocate (openFile fp ReadMode) hClose 15 | go hdl 16 | where 17 | go h = do c <- liftIO $ hIsEOF h 18 | unless c $ do 19 | l <- liftIO $ hGetLine h 20 | yield l 21 | go h 22 | 23 | andThen :: Monad m => MachineT m (k a) b -> MachineT m (k a) b -> MachineT m (k a) b 24 | andThen s1 s2 = MachineT $ do 25 | step <- runMachineT s1 26 | case step of 27 | Stop -> runMachineT s2 28 | Yield o r -> return $ Yield o (andThen r s2) 29 | Await f kt r -> return $ Await (flip andThen s2 . f) kt (andThen r s2) 30 | 31 | numLines :: Monad m => MachineT m (Is a) Int 32 | numLines = fold step (0::Int) where 33 | step s _ = (s+1) 34 | 35 | 36 | 37 | main :: IO () 38 | main = do 39 | (f1:f2: _) <- getArgs 40 | print . head =<< runResourceT (runT $ (lineSource f1 >> {-`andThen`-} lineSource f2) ~> numLines) 41 | -------------------------------------------------------------------------------- /iterative/examples1/pipes-1.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE BangPatterns #-} 2 | import Pipes 3 | import Pipes.Prelude as P 4 | import Data.Char 5 | import System.IO 6 | import System.Environment 7 | import Control.Applicative 8 | import Control.Exception 9 | 10 | numLines :: MonadPlus m => Pipe String Int m () 11 | numLines = go (0::Int) where 12 | go x = (continue x) <|> (yield x) 13 | continue x = do 14 | y <- await 15 | continue (x+(Prelude.length (Prelude.filter (=='\n') y))) 16 | 17 | main :: IO () 18 | main = do 19 | (f:_) <- getArgs 20 | Prelude.print =<< bracket (openFile f ReadMode) 21 | (hClose) 22 | (\hdl -> runEffect $ P.length (fromHandle hdl)) 23 | -------------------------------------------------------------------------------- /iterative/examples1/pipes-2.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE BangPatterns #-} 2 | import Pipes 3 | import Pipes.Prelude as P 4 | import Data.Char 5 | import System.IO 6 | import System.Environment 7 | import Control.Applicative 8 | import Control.Exception 9 | import Control.Monad.Managed 10 | 11 | main :: IO () 12 | main = do 13 | (f1:f2:_) <- getArgs 14 | runManaged $ do 15 | hdl1 <- managed $ withFile f1 ReadMode 16 | hdl2 <- managed $ withFile f2 ReadMode 17 | liftIO . Prelude.print =<< runEffect (P.length (fromHandle hdl1 >> fromHandle hdl2)) 18 | -------------------------------------------------------------------------------- /jobs/Main.hs: -------------------------------------------------------------------------------- 1 | import Control.Concurrent 2 | import Control.Concurrent.STM 3 | import Control.Concurrent.STM.TBQueue 4 | import Control.Monad 5 | import Data.Foldable 6 | 7 | newtype R a = R (TBQueue (TMVar a)) 8 | 9 | steal :: TBQueue (IO b) -> R b -> STM (IO b, TMVar b) 10 | steal q (R r) = do 11 | x <- readTBQueue q 12 | out <- newEmptyTMVar 13 | writeTBQueue r out 14 | pure (x, out) 15 | 16 | await :: R a -> STM a 17 | await (R r) = do 18 | m <- readTBQueue r 19 | takeTMVar m 20 | 21 | 22 | main = do 23 | input <- newTBQueueIO 10 24 | output <- R <$> newTBQueueIO 10 25 | replicateM 5 $ forkIO $ forever $ do 26 | (io, b) <- atomically $ steal input output 27 | atomically . putTMVar b =<< io 28 | for_ tasks $ atomically . writeTBQueue input 29 | forever $ do 30 | print =<< atomically (await output) 31 | where 32 | tasks = zipWith go [(0::Int)..] 33 | [ 300000 34 | , 200000 35 | , 150000 36 | , 600000 37 | , 140000 38 | ] 39 | go n t = do 40 | putStrLn $ show n <> ">" 41 | threadDelay t 42 | putStrLn $ "<" <> show n 43 | pure n 44 | 45 | -------------------------------------------------------------------------------- /postgres-report/dynamic/00.deadlocks.sql: -------------------------------------------------------------------------------- 1 | SELECT blocked_locks.pid AS blocked_pid, 2 | -- blocked_activity.usename AS blocked_user, 3 | blocking_locks.pid AS blocking_pid, 4 | -- blocking_activity.usename AS blocking_user, 5 | blocked_activity.query AS blocked_statement, 6 | blocking_activity.query AS current_statement_in_blocking_process, 7 | age(now(), blocked_activity.query_start) AS "age" 8 | FROM pg_catalog.pg_locks blocked_locks 9 | JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid 10 | JOIN pg_catalog.pg_locks blocking_locks 11 | ON blocking_locks.locktype = blocked_locks.locktype 12 | AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE 13 | AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation 14 | AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page 15 | AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple 16 | AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid 17 | AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid 18 | AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid 19 | AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid 20 | AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid 21 | AND blocking_locks.pid != blocked_locks.pid 22 | JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid 23 | WHERE NOT blocked_locks.GRANTED; 24 | -------------------------------------------------------------------------------- /postgres-report/static/00.general-info.sql: -------------------------------------------------------------------------------- 1 | -- Data anomalies. 2 | -- 3 | -- hit_ration > 90% 4 | -- c_commit_ratio should be > 95% 5 | -- c_rollback_ratio should be < 5% 6 | -- deadlocks should be close to 0 7 | -- conflicts should be close to 0 8 | -- temp_files and temp_bytes watch out for them 9 | select datname, 10 | stats_reset, 11 | (xact_rollback*100)/nullif(xact_commit+xact_rollback, 0) as c_rollback_ratio, 12 | case when blks_hit+blks_read = 0 then null 13 | else blks_hit*100/(blks_hit+blks_read) 14 | end as hit_ratio, 15 | xact_commit, 16 | (xact_commit*100)/nullif(xact_commit+xact_rollback,0) as c_commit_ratio, 17 | xact_rollback, 18 | deadlocks, 19 | conflicts, 20 | tup_deleted, 21 | temp_files, 22 | pg_size_pretty(temp_bytes) temp_bytes 23 | from pg_stat_database; 24 | -------------------------------------------------------------------------------- /postgres-report/static/01.table-size.sql: -------------------------------------------------------------------------------- 1 | SELECT nspname || '.' || relname AS "relation", pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size" 2 | FROM pg_class C 3 | LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) 4 | WHERE nspname NOT IN ('pg_catalog', 'information_schema') AND C.relkind <> 'i' AND nspname !~ '^pg_toast' 5 | ORDER BY pg_total_relation_size(C.oid) DESC; 6 | -------------------------------------------------------------------------------- /postgres-report/static/02.write-activity.sql: -------------------------------------------------------------------------------- 1 | select s.schemaname, s.relname, 2 | pg_size_pretty(pg_relation_size(relid)), 3 | coalesce(n_tup_ins,0) + 2 * coalesce(n_tup_upd,0) - coalesce(n_tup_hot_upd,0) + coalesce(n_tup_del,0) AS total_writes, 4 | (coalesce(n_tup_hot_upd,0)::float * 100 / (case when n_tup_upd > 0 then n_tup_upd else 1 end)::float)::numeric(10,2) AS hot_rate, 5 | coalesce(substring(array_to_string(reloptions, ' ') 6 | FROM 'fillfactor=([0-9]+)')::smallint, 100) AS fillfactor 7 | from pg_stat_user_tables s join pg_class c ON c.oid=relid 8 | where schemaname not like 'pg_%' 9 | order by pg_relation_size(relid) desc; 10 | -------------------------------------------------------------------------------- /postgres-report/static/03.life-data.sql: -------------------------------------------------------------------------------- 1 | select s.schemaname, s.relname, n_live_tup, n_dead_tup, last_autovacuum, autovacuum_count 2 | from pg_stat_user_tables s 3 | order by n_dead_tup desc; 4 | -------------------------------------------------------------------------------- /postgres-report/static/04.indexes-unused.sql: -------------------------------------------------------------------------------- 1 | select * from pg_stat_all_indexes where idx_scan = 0 and not schemaname like 'pg_%' 2 | order by schemaname, relname; 3 | -------------------------------------------------------------------------------- /postgres-report/static/05.table-read-cache-hit.sql: -------------------------------------------------------------------------------- 1 | select schemaname, relname, indexrelname, 2 | (idx_blks_hit+idx_blks_read) total_reads, 3 | case when idx_blks_read+idx_blks_hit = 0 then null else 4 | (100*idx_blks_hit)/(idx_blks_hit+idx_blks_read) end 5 | cache_hit 6 | from pg_statio_all_indexes 7 | where not schemaname like 'pg_%' 8 | order by schemaname, (idx_blks_hit+idx_blks_read) desc; 9 | -------------------------------------------------------------------------------- /regions/info.markdown: -------------------------------------------------------------------------------- 1 | Region-based resource management 2 | ================================ 3 | 4 | For more information see [Oleg's site](http://okmij.org/ftp/Haskell/regions.html) 5 | 6 | Here I'm trying to solve some regions related questions 7 | and experiment. 8 | 9 | All information below was archived based on discussion with Oleg Kiselov, 10 | however I could missinterpret some parts. 11 | 12 | TODO: 13 | ----- 14 | 15 | 2. try to have SMonadIO = RMonadIO 16 | 17 | > It might be interesting to see if SMonadIO can be defined simply as an 18 | > alias 19 | > type SMonadIO = RMonadIO 20 | > It could work if GHC allows exporting SMonadIO but not RMonadIO. This 21 | > requires some experimentation; I'm not sure of exact scoping/alias 22 | > resolution rules. 23 | 24 | 25 | 1. Using resourceForkIO 26 | ------------------------ 27 | 28 | The first problem is how to use monadic regions in presence of concurrency. 29 | The idea is to use `resouceForIO` method that should start a new thread 30 | with some sane region properties. 31 | 32 | 33 | Respecting properties of monadic regions tha is 34 | 35 | > any value that is visible and allowed to be used by typechecker is safe 36 | 37 | leads us to a choice: 38 | 39 | 1. we can start new toplevel 40 | 2. we can start region with current region as a parent 41 | 42 | Former approach is quite restrictive as there will be no way to pass values 43 | to the new region. And as soon will be shown it's possible to express first 44 | using second approach. As we can lift our regionForkIO to upper region we 45 | can select the region that will be shared (up to toplevel one). Then 46 | all resources that exist in shared region and upper will be protected and 47 | available in both regions for their livetime. 48 | 49 | As a result we are building a semi-lattice (i.e. a region tree, where branches 50 | are forks). 51 | 52 | 2. Get rid of overlapping instances. 53 | ------------------------------------ 54 | 55 | > We can do that if we had equality 56 | > predicate, like TEQ in the commented-out section of 57 | > SafeHandles. Previously, TEQ needed overlapping instances. However, it 58 | > can be implemented with closed type families. Therefore, overlapping 59 | > instances are no longer required. I 60 | 61 | While trying to solve TEQ I eventually hit into a possible ghc bug. 62 | see SafeHandlesTEQ.hs 63 | 64 | This is not yet possible and it is a "limitation" from type families. 65 | 66 | Other ideas: 67 | ------------ 68 | 69 | 1. Region tagged variables, it would be nice to tag some pure values that 70 | can delay execution can we unsafe to use outside a region. 71 | From one point of view there should be no such values, but if they stil exists? 72 | 73 | 2. Region variables. Another interesting approach is to use variables that 74 | create region context on their own. This will allow to pass resources between 75 | regions in a safe way (but with unsafe internals). 76 | 77 | data RContext = .. 78 | putRContext :: RContext -> handle s -> R s m () 79 | useRContext :: RConctext -> (forall q {-such s is q`s parent-} . handle q -> R q a) -> R s a 80 | 81 | so region variable is capable for a livetime of values that are inside it. 82 | This approach have downsides, for example if resource allocation locks some 83 | external resource then we can't reason about the time when resource is free 84 | to allocate again. (Same true for regionForkIO). 85 | -------------------------------------------------------------------------------- /regions/typed-device/main.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE ExistentialQuantification #-} 2 | {-# LANGUAGE TypeFamilies #-} 3 | {-# LANGUAGE DataKinds #-} 4 | {-# LANGUAGE GADTs #-} 5 | {-# LANGUAGE StandaloneDeriving #-} 6 | {-# LANGUAGE KindSignatures #-} 7 | {-# LANGUAGE FlexibleContexts #-} 8 | {-# LANGUAGE DeriveDataTypeable #-} 9 | {-# LANGUAGE Rank2Types #-} 10 | {-# LANGUAGE FlexibleInstances #-} 11 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 12 | {-# LANGUAGE ConstraintKinds #-} 13 | 14 | import Control.Applicative 15 | import Data.Bifunctor (second) 16 | import Data.IntMap (IntMap) 17 | import qualified Data.IntMap as Map 18 | import Control.Concurrent 19 | import System.IO.Unsafe 20 | import Data.Typeable 21 | import Data.Proxy 22 | 23 | -- Typed device index 24 | class MkDevice a where 25 | mkDevice :: Cthulhu s -> Int -> SIO s a 26 | 27 | data family DeviceIndex a :: * 28 | class HaveIndex a where getIndex :: a -> Int 29 | -- Hack, because we can't create Typeable instances for data families: 30 | class ToDevRep a where 31 | type Rep a :: * 32 | toDevRep :: a -> Proxy (Rep a) 33 | toDevRep _ = Proxy 34 | instance ToDevRep a => ToDevRep (Proxy a) where 35 | type Rep (Proxy a) = a 36 | class HaveMigo s where haveMiGo :: 37 | -- Devices 38 | data DeviceA s = DeviceA { 39 | deviceAI :: Int 40 | , deviceAprotect :: !(MiGo s) 41 | } deriving Typeable 42 | instance MkDevice (DeviceA s) where 43 | mkDevice c i = fmap DeviceA (callToCthulhu c i) 44 | newtype instance DeviceIndex (DeviceA s) = IA Int 45 | instance HaveIndex (DeviceIndex (DeviceA s)) where getIndex (IA i) = i 46 | data DeviceARep = DeviceARep deriving Typeable 47 | instance ToDevRep (DeviceIndex (DeviceA s)) where 48 | type Rep (DeviceIndex (DeviceA s)) = DeviceARep 49 | 50 | data DeviceB s = DeviceB { 51 | deviceBI :: String 52 | } deriving Typeable 53 | instance MkDevice (DeviceB s) where 54 | mkDevice c i = fmap DeviceB (callToCthulhu c (show i)) 55 | newtype instance DeviceIndex (DeviceB s) = IB Int 56 | instance HaveIndex (DeviceIndex (DeviceB s)) where getIndex (IB i) = i 57 | data DeviceBRep = DeviceBRep deriving Typeable 58 | instance ToDevRep (DeviceIndex (DeviceB s)) where 59 | type Rep (DeviceIndex (DeviceB s)) = DeviceBRep 60 | 61 | data Cthulhu s = Cthulhu -- not exported 62 | 63 | callToCthulhu :: Cthulhu s -> a -> SIO s a 64 | callToCthulhu _ a = return a 65 | 66 | 67 | data MiGo s = MiGo -- not exported 68 | 69 | type XXX g s = (ToDevRep (DeviceIndex (g s)), Typeable (Rep (DeviceIndex (g s))), HaveIndex (DeviceIndex (g s)), MkDevice (g s)) 70 | 71 | data SomeIndex = forall a . Typeable a => SomeIndex a 72 | 73 | newtype SIO s a = SIO {runSIO :: IO a} deriving (Functor, Applicative, Monad) 74 | 75 | 76 | withDevice :: XXX g s => DeviceIndex (g s) -> (forall s . g s -> SIO s b) -> IO b 77 | withDevice d f = registering d $ \mk -> runSIO $ mk >>= f 78 | 79 | registering :: XXX g s => DeviceIndex (g s) -> (SIO s (g s) -> IO b) -> IO b 80 | registering d f = 81 | case mv of 82 | Nothing -> error "register: no such device" 83 | Just mtx -> 84 | withMVar mtx $ \(SomeIndex d') -> 85 | if typeOf d' == typeRep (toDevRep d) 86 | then f (mkDevice Cthulhu (getIndex d)) 87 | else error "register: type mismatch" 88 | where 89 | mv = getIndex d `Map.lookup` registry 90 | 91 | registry :: IntMap (MVar SomeIndex) 92 | registry = Map.fromList 93 | $ map (second (unsafePerformIO . newMVar)) 94 | $ [(1, SomeIndex DeviceARep) , (2, SomeIndex DeviceARep), (3, SomeIndex DeviceBRep)] 95 | {-# NOINLINE registry #-} 96 | 97 | doOnA :: DeviceA s -> SIO s () 98 | doOnA (DeviceA i) = SIO $ print i 99 | 100 | test1 = withDevice (IA 1) $ \onDevice -> doOnA onDevice 101 | -- Runtime exception: 102 | test2 = withDevice (IA 3) $ \onDevice -> doOnA onDevice 103 | -- Doesn't compile as 's' escapes from it's scope 104 | -- test3 = withDevice (IB 2) $ return 105 | -------------------------------------------------------------------------------- /series/2.lhs: -------------------------------------------------------------------------------- 1 | 2 | > import Data.Stream (Stream(..), (<:>)) 3 | > import qualified Data.Stream as S 4 | 5 | > newtype T a = T { unT :: Stream a } 6 | 7 | > instance Functor T where 8 | > fmap f (T s) = T (fmap f s) 9 | 10 | Also we may give a 'Num' instance for simplicity: 11 | 12 | 13 | > instance Num a => Num (T a) where 14 | > (T x) + (T y) = T (S.zipWith (+) x y) 15 | > abs s = fmap abs s 16 | > negate s = fmap negate s 17 | > signum s = fmap signum s 18 | > (T (Cons a x)) * (T (Cons b y)) = T $ (a * b) <:> unT ( T (fmap (*a) y) + T (fmap (*b) x) + T (0 <:> unT (T x * T y))) 19 | > fromInteger x = T $ (fromInteger x) <:> unT 0 20 | 21 | > instance Fractional a => Fractional (T a) where 22 | > fromRational x = T (fromRational x <:> unT 0) 23 | 24 | > instance Floating a => Floating (T a) where 25 | > pi = T $ pi <:> unT 0 26 | 27 | > power :: Num a => a -> T a 28 | > power x = T $ 1 <:> S.iterate (*x) x 29 | 30 | > (^.^) :: Num a => T a -> T a -> T a 31 | > s1 ^.^ s2 = go s1 (power s2) 32 | > where 33 | > go :: Num a => T a -> T (T a) -> T a 34 | > go a (T (Cons b bs)) = T $ S.zipWith (+) (unT (a * b)) (0 <:> unT (go a (T bs))) 35 | 36 | 37 | -------------------------------------------------------------------------------- /sum/post2.md.lhs: -------------------------------------------------------------------------------- 1 | > {-# LANGUAGE DataKinds #-} 2 | > {-# LANGUAGE KindSignatures #-} 3 | > {-# LANGUAGE ScopedTypeVariables #-} 4 | > {-# LANGUAGE PolyKinds #-} 5 | > {-# LANGUAGE TypeOperators #-} 6 | > {-# LANGUAGE FlexibleInstances #-} 7 | > {-# OPTIONS_GHC -Wall #-} 8 | 9 | > import Data.Proxy 10 | > import Data.Monoid 11 | 12 | Наш заказ как он есть, без всякой доп инфы 13 | 14 | > type Order = Double 15 | 16 | Заказ, как он хранится в базе, где на него могут навешать всяких 17 | интересных тегов. 18 | 19 | > data TaggedOrder = TaggedOrder 20 | > { getOrder :: Order 21 | > , isSent :: Bool 22 | > , isPrepaid :: Bool 23 | > , isRisky :: Bool 24 | > } 25 | 26 | > withOrder :: TaggedOrder -> (Order -> Order) -> TaggedOrder 27 | > withOrder t f = t{ getOrder = f (getOrder t) } 28 | 29 | Интересные нам свойства 30 | 31 | > data Prop = IsPrepaid | IsSent | IsRisk 32 | 33 | Свойства изменения оплаты 34 | 35 | > data OrderProp = Increase | Decrease 36 | 37 | Попробуем красиво записать правила: 38 | 39 | > data Rule (p :: [Prop]) (o :: [OrderProp]) (a :: Action) 40 | 41 | > data Action = Deny -- ^ Отменить изменение 42 | > | Pass -- ^ Разрешить изменение 43 | > | RiskCheck Action Action -- ^ сделать RiskCheck 44 | > deriving (Eq, Show) 45 | 46 | > instance Monoid Action where 47 | > mempty = Pass 48 | > mappend Deny _ = Deny 49 | > mappend _ Deny = Deny 50 | > mappend (RiskCheck a b) c = RiskCheck (a `mappend` c) (b `mappend` c) 51 | > mappend Pass x = x 52 | 53 | > type Rules1 = [ Rule '[ 'IsPrepaid, 'IsSent] '[] 'Deny 54 | > , Rule '[ 'IsPrepaid] '[ 'Decrease] 'Deny 55 | > , Rule '[] '[ 'Increase] ('RiskCheck 'Deny 'Pass) 56 | > , Rule '[ 'IsRisk] '[] 'Deny 57 | > ] 58 | 59 | Данное решение не совсем честное, т.к. на самом деле перестанет работать в случае, 60 | если у нас появятся модификаторы тегов, а они точно появятся. 61 | 62 | > interpret :: Action -> TaggedOrder -> Double -> IO (Either String TaggedOrder) 63 | > interpret Pass to d = return $ pure (withOrder to (+d)) 64 | > interpret Deny _to _d = return $ fail "Order was blocked" 65 | > interpret (RiskCheck no ok) to d = do 66 | > b <- performRiskCheck (getOrder to) 67 | > if b then interpret ok to d 68 | > else interpret no to d 69 | 70 | > performRiskCheck :: Order -> IO Bool 71 | > performRiskCheck = undefined 72 | 73 | 74 | > class MkRules (c :: k) where 75 | > mkRules :: proxy c -> TaggedOrder -> Double -> Action 76 | 77 | 78 | > instance MkRules '[] where 79 | > mkRules _ _ _ = Pass 80 | 81 | > instance (HasPaymentTags i, HasOrderTags s, MkAction a, MkRules rs) => MkRules (Rule s i a ': rs) where 82 | > mkRules _ t d 83 | > | hasOrderTags (Proxy :: Proxy s) t && hasPaymentTags (Proxy :: Proxy i) d 84 | > = mkAction (Proxy :: Proxy a) <> mkRules (Proxy :: Proxy rs) t d 85 | > | otherwise = mkRules (Proxy :: Proxy rs) t d 86 | 87 | > class MkAction (a::Action) where mkAction :: proxy a -> Action 88 | > instance MkAction 'Pass where mkAction _ = Pass 89 | > instance MkAction 'Deny where mkAction _ = Deny 90 | > instance (MkAction a, MkAction b) => MkAction ('RiskCheck a b) where 91 | > mkAction _ = RiskCheck (mkAction (Proxy :: Proxy a)) (mkAction (Proxy :: Proxy b)) 92 | 93 | 94 | > class HasOrderTags c where hasOrderTags :: proxy c -> TaggedOrder -> Bool 95 | > instance HasOrderTags '[] where hasOrderTags _ _ = True 96 | > instance HasOrderTags ps => HasOrderTags ('IsPrepaid ': ps) where 97 | > hasOrderTags _ to = isPrepaid to && hasOrderTags (Proxy :: Proxy ps) to 98 | > instance HasOrderTags ps => HasOrderTags ('IsSent ': ps) where 99 | > hasOrderTags _ to = isSent to && hasOrderTags (Proxy :: Proxy ps) to 100 | > instance HasOrderTags ps => HasOrderTags ('IsRisk ': ps) where 101 | > hasOrderTags _ to = isRisky to && hasOrderTags (Proxy :: Proxy ps) to 102 | 103 | > class HasPaymentTags c where hasPaymentTags :: proxy c -> Double -> Bool 104 | > instance HasPaymentTags '[] where hasPaymentTags _ _ = True 105 | > instance HasPaymentTags ps => HasPaymentTags ('Increase ': ps) where 106 | > hasPaymentTags _ d = d >= 0 && hasPaymentTags (Proxy :: Proxy ps) d 107 | > instance HasPaymentTags ps => HasPaymentTags ('Decrease ': ps) where 108 | > hasPaymentTags _ d = d < 0 && hasPaymentTags (Proxy :: Proxy ps) d 109 | 110 | 111 | > step1Rules :: Proxy Rules1 112 | > step1Rules = Proxy 113 | 114 | *Main> mkRules step1Rules (TaggedOrder 100 True True True) 15 115 | Deny 116 | *Main> mkRules step1Rules (TaggedOrder 100 True True False) 15 117 | Deny 118 | *Main> mkRules step1Rules (TaggedOrder 100 True False False) 15 119 | RiskCheck Deny Pass 120 | *Main> mkRules step1Rules (TaggedOrder 100 True False False) (-15) 121 | Pass 122 | -------------------------------------------------------------------------------- /talks/AS talk - From my son’s windows laptop to the cloud.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/AS talk - From my son’s windows laptop to the cloud.pdf -------------------------------------------------------------------------------- /talks/cloud-haskell/images/c-h-architecture.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/cloud-haskell/images/c-h-architecture.pdf -------------------------------------------------------------------------------- /talks/cloud-haskell/images/c-h-architecture.pdf_tex: -------------------------------------------------------------------------------- 1 | %% Creator: Inkscape inkscape 0.91, www.inkscape.org 2 | %% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010 3 | %% Accompanies image file 'c-h-architecture.pdf' (pdf, eps, ps) 4 | %% 5 | %% To include the image in your LaTeX document, write 6 | %% \input{.pdf_tex} 7 | %% instead of 8 | %% \includegraphics{.pdf} 9 | %% To scale the image, write 10 | %% \def\svgwidth{} 11 | %% \input{.pdf_tex} 12 | %% instead of 13 | %% \includegraphics[width=]{.pdf} 14 | %% 15 | %% Images with a different path to the parent latex file can 16 | %% be accessed with the `import' package (which may need to be 17 | %% installed) using 18 | %% \usepackage{import} 19 | %% in the preamble, and then including the image with 20 | %% \import{}{.pdf_tex} 21 | %% Alternatively, one can specify 22 | %% \graphicspath{{/}} 23 | %% 24 | %% For more information, please see info/svg-inkscape on CTAN: 25 | %% http://tug.ctan.org/tex-archive/info/svg-inkscape 26 | %% 27 | \begingroup% 28 | \makeatletter% 29 | \providecommand\color[2][]{% 30 | \errmessage{(Inkscape) Color is used for the text in Inkscape, but the package 'color.sty' is not loaded}% 31 | \renewcommand\color[2][]{}% 32 | }% 33 | \providecommand\transparent[1]{% 34 | \errmessage{(Inkscape) Transparency is used (non-zero) for the text in Inkscape, but the package 'transparent.sty' is not loaded}% 35 | \renewcommand\transparent[1]{}% 36 | }% 37 | \providecommand\rotatebox[2]{#2}% 38 | \ifx\svgwidth\undefined% 39 | %\setlength{\unitlength}{300.525bp}% 40 | \setlength{\unitlength}{250.525bp}% 41 | \ifx\svgscale\undefined% 42 | \relax% 43 | \else% 44 | \setlength{\unitlength}{\unitlength * \real{\svgscale}}% 45 | \fi% 46 | \else% 47 | \setlength{\unitlength}{\svgwidth}% 48 | \fi% 49 | \global\let\svgwidth\undefined% 50 | \global\let\svgscale\undefined% 51 | \makeatother% 52 | \begin{picture}(1,0.91706181)% 53 | \put(0,0){\includegraphics[width=\unitlength,page=1]{images/c-h-architecture.pdf}}% 54 | \put(0.26044006,0.30213793){\color[rgb]{0,0,0}\makebox(0,0)[b]{\smash{\textbf{network-transport}}}}% 55 | \put(0,0){\includegraphics[width=\unitlength,page=2]{images/c-h-architecture.pdf}}% 56 | \put(0.26044006,0.54171866){\color[rgb]{0,0,0}\makebox(0,0)[b]{\smash{\textbf{distributed-process}}}}% 57 | \put(0,0){\includegraphics[width=\unitlength,page=3]{images/c-h-architecture.pdf}}% 58 | \put(0.73960153,0.54171866){\color[rgb]{0,0,0}\makebox(0,0)[b]{\smash{\textbf{distributed-process-backend}}}}% 59 | \put(0,0){\includegraphics[width=\unitlength,page=4]{images/c-h-architecture.pdf}}% 60 | \put(0.73960153,0.30213793){\color[rgb]{0,0,0}\makebox(0,0)[b]{\smash{\textbf{network-transport-backend}}}}% 61 | \put(0,0){\includegraphics[width=\unitlength,page=5]{images/c-h-architecture.pdf}}% 62 | \put(0.26044006,0.80791947){\color[rgb]{0,0,0}\makebox(0,0)[b]{\smash{\textbf{distributed-algrorithm}}}}% 63 | \put(0,0){\includegraphics[width=\unitlength,page=6]{images/c-h-architecture.pdf}}% 64 | \put(0.73960153,0.80791947){\color[rgb]{0,0,0}\makebox(0,0)[b]{\smash{\textbf{user application}}}}% 65 | \put(0,0){\includegraphics[width=\unitlength,page=7]{images/c-h-architecture.pdf}}% 66 | \put(0.73960153,0.06255719){\color[rgb]{0,0,0}\makebox(0,0)[b]{\smash{\textbf{network-library}}}}% 67 | \put(0,0){\includegraphics[width=\unitlength,page=8]{images/c-h-architecture.pdf}}% 68 | \end{picture}% 69 | \endgroup% 70 | -------------------------------------------------------------------------------- /talks/cloud-haskell/images/c-h-architecture.xml: -------------------------------------------------------------------------------- 1 | 7Vlbb+I8EP01PLLKpaTtY2/bffmkSmi1+z2axE2sOnHkmAL76zt2xrkCChSFIvUJexyPx+eMjydk4j+k62dJ8uQ/EVE+8ZxoPfEfJ57nOe4N/GjLprTc+G5piCWLSlPDMGf/KBodtC5ZRIvWg0oIrljeNoYiy2ioWrZXwdtL5CS27mvDPCS8b/3DIpVgyF5Q239RFid2GTe4LUcKtbE+IvpKllxNjQnG9HBKrC+zK/8JEJNCgBvdStcPlGvULCDl1n/uGK2ClDTDQPZPwCDeCV9ijBlVKyHfpkqSrMiFVBMv4ODrfiGhFetWb1+rhCk6z0mo+ysgGx5KVMqh50JzA2uKFTReRabmOE0PmH5JqxtUjt+pVBSTZMuGjAl380xFSpXcwCM4YeoGmB2YVN419lc1ay6i4iQNxuw8gskTV75r/KCBEG6H0+/BGbFCSbZYKhpNcylCWhSHwrcwzs4CnnszInhXQ8CbQhKSVCNUJiUJ32gWVcaj8nM8gC1054AXhWrfUR8G7iXJQQfwUcVg1gO8hxSN4I7BLuCfiFhkhD/V1nsplllEtUenjWLpSzvYDw2sJ5bSUFELlCIypviUOXZ9ACXlRLH3tvfPwHH9BeFAyWnCYY7JCHBg7bND7QiPhWQqSQ++LWJJaXam62JMOcPqqoHf74KCJjl3ec5ZCGSJ7PNaJUAadUqdQavGBNPdXQdytpBEMqizD4RO6mN6Btx8C8gowA0R+Sy6k1LfeI8hJ0XBwjZQdM3UX61oP2bY+9+OZBBOY0h39ZjWvpPpvwm4D24DvdkW8KxtsC7iCi+CQXi1hAROm72pZcr6KKPHac03ma6nmQ3JerJ3vfVUbrrnyVBcbXwY6/1a6mjWbdvwWtNsWG9xbsaOYx2jG3DNfbO+h/UhFczQs77rpFcde85N54VKBpHC/VZP7dqOSw28RpupYTTiOzUOSo1+NXd4amxPgepS6KbNZwRhC+tmB+di3TJj34ttDnxpzvsV6Amv/pPxuuP1bqzTfNvho1t0DWY2uOp4cu3fwKen1krOpVR1qD5fSMQvk3bc6KXQjlVok/byRe6b9328Q7f+wFI+Xn+f8p8+AA== -------------------------------------------------------------------------------- /talks/cloud-haskell/images/c-h-d-p: -------------------------------------------------------------------------------- 1 | 5VpLd6M2FP41XqYnGPxaTh4zs8l0erLodElABk4xcgWOk/76uYJ7QUKYIbZC7NYbw5WQxKfvPsXEvd28fBH+Nn7gIUsn0+vwZeLeTabT6bWzhD8peSXJ9XUliUQSVjKnETwm/zIUUrddErJc61hwnhbJVhcGPMtYUGiyNU/1KbZ+RMM3gsfAT03pn0lYxJV0OZ038q8siWKaxpmvqpa8eKUxQrb2d2lxVYqgTTZvfBqrfCv3HiATnMMw8mrzcstSCRsBUr365wOt9SIFy3Ah/Q/Mqgee/XSHazQWncf+Vl5KxJiYuDf7OCnY49YPpHQPewuyuNikcOfAZeE/EUCON68ENTLeAgSvsAa+x5mZKBhSomP1pQiX/oXxDSvEK3TBB65mHlIBKXTlEoX2zR7NXJTFyv7MiEQ+ciWqR2/gggtErBs92vw++OAJ4CPc/Aq3Nc8K5LgrYYsEY5kNkKYtkJwOjJYdEJHsJIQGEOwMECKGEEJEjhEQctBM9CH0Rly48DMwZjb0C81HrV/OzERmSjIVGjvYoIc4T2yIJDU2pGcqNh4qgIbNygI2pun59vvd/WQ6T2GWmycBV5G8MgCDV5ZyBaO8EPxvdstTDub9LuOZ1MV1kqYtkZ8mUQa3AUBUegIJYAIu8hM2bJIwlNN0KjKH3mtp9927GPqB5pq7Y2NfnMUAn+B0qTPx+JRtWZwzYwmImrGk3r9krBVtxjEUbL4LHrA8PxUilauTqbsufwaxoQUiTBlk2iGaCSe5EZVobgecZChOQhMXrKI5QPs/3tl6xCWEbT6irzWjkW/w0AWAVsdsxLWaQ2PAZvqah68XCduYcZ3pCR78JH3iLwOQeyNeoZ/HTM4rG5/kfBawc1tBcQOmat7Ig6jwkUaflDjgGCqdQkjI8ZaLIuYRz/z0vpHeCL7LwhIIaeMVwNhLUvyQ4t8WM7z9C3sBHOJVbZP31Ngdn8iF9KMK6+Y7Ue6ewrrCFxGjbk22r6EvWOoXybM+/klA0oLsAqmiqABXt9UoVo2WgMRcSQOylI0BJEZyqkL/cSG6XIe7faEKxc1a4Ed6eBJynoncj3MsA7Sy3a7w+L3cBe1Hb6EkCz8JUWZQQerneRL0A9NYPdXoyZ5Hqh+GT6r6Vcs0MVXrbz2p1mAtxRm+8wQW2GzZggaqk712bF29AD6nVkKNodohlttO06v3NoaCPfHlK1O3rexQ5jQHZiL/WMdyWo0WLqoRG97UuA6jkpkZvBOVmkzqzVQqQ8r/Am3qWmFrNy+ONaaRtscaLVrQgoUyqGiCBdl2HKNouVpsUMbgH8cyoxLV9hTDjVO7EOuRw7BNM4esXjfPBjyAb22NmEOOEKx5xnGIWUVEH0bMZdtmnUDMtll6P2K2c3k02dZ4NuQwz5oB3O7EFkY9znliaUEzdQdi27EYZc+hLkeLw7z26bFty9V1GFDli5IoGrXm/+zkmX/ZcJWXFPoEHZzlVtaLsJFyTMECJjcLB4N1VONRBnrRZ0DyXinZr1au+xl2xErJ3oPvD7QdJ2oparJ6p4K9ax5mChYlAHw1zLnVDNqfDTTp8Rj1P3fAsbhijZGdfab4QHmKAoDa52tm+jgDTVutGeiSVh8Xi7YrQMYh9HCX3y4MG7b+gIE+woTSyH00CHbiuWa/FQ9ttUJyqED5P9r4N3tm10h2EY6Da2ufKtbWypYz97qqKjacOZj5PZQvTZ99wLmfsSvX/NCofn2GZqHNF81XkXae6NnhtvlAs2JS84Gre/8T -------------------------------------------------------------------------------- /talks/cloud-haskell/images/c-h-d-p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/cloud-haskell/images/c-h-d-p.png -------------------------------------------------------------------------------- /talks/cloud-haskell/images/c-h-n-t.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/cloud-haskell/images/c-h-n-t.png -------------------------------------------------------------------------------- /talks/cloud-haskell/images/c-h-n-t.xml: -------------------------------------------------------------------------------- 1 | 7Vnfb9s2EP5rDGwPDvTDsdPHOMnaASsWIAO2PXISLQmlRYGiY3t/fe+ko0SJcqM4CtKsAwyDPNHH4/d9Rx7lWXizPXxUrEg/y5iLWeDFh1l4OwsCf3kZXqyuoIXGIxlXi+WFR8ZEZTGZW8ND9i8no0fWXRbzsjNQSyl0VnSNkcxzHumObSNFd4qCJcZ9a3iImHCtf2axTmvrVbBs7Z94lqRmGn/5oX5S6qPxEfMN2wk9r0zwDB9vmfFVrSq8A+CUlOAGW9vDDRcIngGkXvovJ542QSqeUyDf/kFIUD4ysaMgnaj3aab5Q8Ei7O+B0Vm4TvVWQM+HZqI4z8kLV5oblt1QKhPF8ZHLLdfqCEPoB/PVqv4JKeKKQtu3aAchDUktpJc0jhHpSeO5XTc0aOnDMBCJFgp3eXwvM4g8WAqYaP2PglaCrXGW52F4hHDkfgoQfQObySsXRTNiahCJm/cPou89iaHBa2oMac/4VjqWKSuwGe2UOK4Vi75wROsJcJTc5THHWbA3hdIaWE6jRJtPByXfGF8Ck0/hDmrtBF6xjHbbanFPYfV62fhhXDYupoCIlGNB9IdieVlINZiPPdRg0Wi3UCm1kl/4jRRSgSWXOYxcbzIheiYmsiRHfQJIHOxrhDCDg/SaHmyzOMZpBmmQMHqD6Ie3KYyDkwW1q5nOJP52DghOJN9VlxqTvRY1vpG0zc0k8r0cn+YbwQ/XSiEia57H1LyNBCvLLKp4YUq7Zos5fsj0X1b7b2h7F5e1Q1PMBFd1n8qs1cUC0Kudd4ZUlu4gAxnsXuG62KkC1lAth8dOTdXjB5Ysd6oSQHsMwwwJ7mnNoeKyaLF0OUCSsSkuQDmP3SCGmKMZaAdpRLLo5e/cN6oxTurw252nKbQcV6bUMq4cJdXLdlxVYmqWPk5fbj3j6GtQS7ZocpgOVYMJV3Va2Yxn9/uh0uQ3wd/fYsfy+ISbExwC0gzXaoYVOKAciJbcklZaBdQOztaDW5r9r4f3pAda9GR6oHv2i/RAh0olh86hct7e/6ZqmEgM8/7NYaQczqFwxE3BopBqM4u/mJVpcx/Azj3TUK9hkQXweYuzibTeY7wBk8aNuZSYEu65VJrDubshvwKRZiKLyN8QlX2NTfP2Cuvfcy7N31MhP8ndvFdFDZTtQ5fzKcp2E+3zcq6TaBYNZ2ZXNeWbnZp9+M9Nr/7x+4r55d6DP3H2eByZX//tbGrvM2+ST6FDTQn5A5ZZeI2fwLuxyPHmQAvbIhxEjveZlyW+tx969uvv8PXTzz8gqatF78Xc0Jv01+KU5rY4jYQskaKxpP7AxPWKl6FkHNrdpyAudA835Ol9bo0bmesHCs2sa0pmBv6bMq92X8gLdNt//+rjrv0PNbz7Cg== -------------------------------------------------------------------------------- /talks/cloud-haskell/talk.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/cloud-haskell/talk.pdf -------------------------------------------------------------------------------- /talks/ffi/presentation/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .svn 3 | log/*.log 4 | tmp/** 5 | node_modules/ 6 | .sass-cache 7 | css/reveal.min.css 8 | js/reveal.min.js 9 | -------------------------------------------------------------------------------- /talks/ffi/presentation/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 4.1.1 4 | before_script: 5 | - npm install -g grunt-cli -------------------------------------------------------------------------------- /talks/ffi/presentation/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Please keep the [issue tracker](http://github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**. 4 | 5 | 6 | ### Personal Support 7 | If you have personal support or setup questions the best place to ask those are [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js). 8 | 9 | 10 | ### Bug Reports 11 | When reporting a bug make sure to include information about which browser and operating system you are on as well as the necessary steps to reproduce the issue. If possible please include a link to a sample presentation where the bug can be tested. 12 | 13 | 14 | ### Pull Requests 15 | - Should follow the coding style of the file you work in, most importantly: 16 | - Tabs to indent 17 | - Single-quoted strings 18 | - Should be made towards the **dev branch** 19 | - Should be submitted from a feature/topic branch (not your master) 20 | 21 | 22 | ### Plugins 23 | Please do not submit plugins as pull requests. They should be maintained in their own separate repository. More information here: https://github.com/hakimel/reveal.js/wiki/Plugin-Guidelines 24 | -------------------------------------------------------------------------------- /talks/ffi/presentation/Gruntfile.js: -------------------------------------------------------------------------------- 1 | /* global module:false */ 2 | module.exports = function(grunt) { 3 | var port = grunt.option('port') || 8000; 4 | var base = grunt.option('base') || '.'; 5 | 6 | // Project configuration 7 | grunt.initConfig({ 8 | pkg: grunt.file.readJSON('package.json'), 9 | meta: { 10 | banner: 11 | '/*!\n' + 12 | ' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' + 13 | ' * http://lab.hakim.se/reveal-js\n' + 14 | ' * MIT licensed\n' + 15 | ' *\n' + 16 | ' * Copyright (C) 2015 Hakim El Hattab, http://hakim.se\n' + 17 | ' */' 18 | }, 19 | 20 | qunit: { 21 | files: [ 'test/*.html' ] 22 | }, 23 | 24 | uglify: { 25 | options: { 26 | banner: '<%= meta.banner %>\n' 27 | }, 28 | build: { 29 | src: 'js/reveal.js', 30 | dest: 'js/reveal.min.js' 31 | } 32 | }, 33 | 34 | sass: { 35 | core: { 36 | files: { 37 | 'css/reveal.css': 'css/reveal.scss', 38 | } 39 | }, 40 | themes: { 41 | files: [ 42 | { 43 | expand: true, 44 | cwd: 'css/theme/source', 45 | src: ['*.scss'], 46 | dest: 'css/theme', 47 | ext: '.css' 48 | } 49 | ] 50 | } 51 | }, 52 | 53 | autoprefixer: { 54 | dist: { 55 | src: 'css/reveal.css' 56 | } 57 | }, 58 | 59 | cssmin: { 60 | compress: { 61 | files: { 62 | 'css/reveal.min.css': [ 'css/reveal.css' ] 63 | } 64 | } 65 | }, 66 | 67 | jshint: { 68 | options: { 69 | curly: false, 70 | eqeqeq: true, 71 | immed: true, 72 | latedef: true, 73 | newcap: true, 74 | noarg: true, 75 | sub: true, 76 | undef: true, 77 | eqnull: true, 78 | browser: true, 79 | expr: true, 80 | globals: { 81 | head: false, 82 | module: false, 83 | console: false, 84 | unescape: false, 85 | define: false, 86 | exports: false 87 | } 88 | }, 89 | files: [ 'Gruntfile.js', 'js/reveal.js' ] 90 | }, 91 | 92 | connect: { 93 | server: { 94 | options: { 95 | port: port, 96 | base: base, 97 | livereload: true, 98 | open: true 99 | } 100 | } 101 | }, 102 | 103 | zip: { 104 | 'reveal-js-presentation.zip': [ 105 | 'index.html', 106 | 'css/**', 107 | 'js/**', 108 | 'lib/**', 109 | 'images/**', 110 | 'plugin/**', 111 | '**.md' 112 | ] 113 | }, 114 | 115 | watch: { 116 | options: { 117 | livereload: true 118 | }, 119 | js: { 120 | files: [ 'Gruntfile.js', 'js/reveal.js' ], 121 | tasks: 'js' 122 | }, 123 | theme: { 124 | files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ], 125 | tasks: 'css-themes' 126 | }, 127 | css: { 128 | files: [ 'css/reveal.scss' ], 129 | tasks: 'css-core' 130 | }, 131 | html: { 132 | files: [ 'index.html'] 133 | }, 134 | markdown: { 135 | files: [ './*.md' ] 136 | } 137 | } 138 | 139 | }); 140 | 141 | // Dependencies 142 | grunt.loadNpmTasks( 'grunt-contrib-qunit' ); 143 | grunt.loadNpmTasks( 'grunt-contrib-jshint' ); 144 | grunt.loadNpmTasks( 'grunt-contrib-cssmin' ); 145 | grunt.loadNpmTasks( 'grunt-contrib-uglify' ); 146 | grunt.loadNpmTasks( 'grunt-contrib-watch' ); 147 | grunt.loadNpmTasks( 'grunt-sass' ); 148 | grunt.loadNpmTasks( 'grunt-contrib-connect' ); 149 | grunt.loadNpmTasks( 'grunt-autoprefixer' ); 150 | grunt.loadNpmTasks( 'grunt-zip' ); 151 | 152 | // Default task 153 | grunt.registerTask( 'default', [ 'css', 'js' ] ); 154 | 155 | // JS task 156 | grunt.registerTask( 'js', [ 'jshint', 'uglify', 'qunit' ] ); 157 | 158 | // Theme CSS 159 | grunt.registerTask( 'css-themes', [ 'sass:themes' ] ); 160 | 161 | // Core framework CSS 162 | grunt.registerTask( 'css-core', [ 'sass:core', 'autoprefixer', 'cssmin' ] ); 163 | 164 | // All CSS 165 | grunt.registerTask( 'css', [ 'sass', 'autoprefixer', 'cssmin' ] ); 166 | 167 | // Package presentation to archive 168 | grunt.registerTask( 'package', [ 'default', 'zip' ] ); 169 | 170 | // Serve presentation locally 171 | grunt.registerTask( 'serve', [ 'connect', 'watch' ] ); 172 | 173 | // Run tests 174 | grunt.registerTask( 'test', [ 'jshint', 'qunit' ] ); 175 | 176 | }; 177 | -------------------------------------------------------------------------------- /talks/ffi/presentation/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2015 Hakim El Hattab, http://hakim.se 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /talks/ffi/presentation/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reveal.js", 3 | "version": "3.2.0", 4 | "main": [ 5 | "js/reveal.js", 6 | "css/reveal.css" 7 | ], 8 | "homepage": "http://lab.hakim.se/reveal-js/", 9 | "license": "MIT", 10 | "description": "The HTML Presentation Framework", 11 | "authors": [ 12 | "Hakim El Hattab " 13 | ], 14 | "dependencies": { 15 | "headjs": "~1.0.3" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git://github.com/hakimel/reveal.js.git" 20 | }, 21 | "ignore": [ 22 | "**/.*", 23 | "node_modules", 24 | "bower_components", 25 | "test" 26 | ] 27 | } -------------------------------------------------------------------------------- /talks/ffi/presentation/css/print/pdf.css: -------------------------------------------------------------------------------- 1 | /** 2 | * This stylesheet is used to print reveal.js 3 | * presentations to PDF. 4 | * 5 | * https://github.com/hakimel/reveal.js#pdf-export 6 | */ 7 | 8 | * { 9 | -webkit-print-color-adjust: exact; 10 | } 11 | 12 | body { 13 | margin: 0 auto !important; 14 | border: 0; 15 | padding: 0; 16 | float: none !important; 17 | overflow: visible; 18 | } 19 | 20 | html { 21 | width: 100%; 22 | height: 100%; 23 | overflow: visible; 24 | } 25 | 26 | /* Remove any elements not needed in print. */ 27 | .nestedarrow, 28 | .reveal .controls, 29 | .reveal .progress, 30 | .reveal .playback, 31 | .reveal.overview, 32 | .fork-reveal, 33 | .share-reveal, 34 | .state-background { 35 | display: none !important; 36 | } 37 | 38 | h1, h2, h3, h4, h5, h6 { 39 | text-shadow: 0 0 0 #000 !important; 40 | } 41 | 42 | .reveal pre code { 43 | overflow: hidden !important; 44 | font-family: Courier, 'Courier New', monospace !important; 45 | } 46 | 47 | ul, ol, div, p { 48 | visibility: visible; 49 | position: static; 50 | width: auto; 51 | height: auto; 52 | display: block; 53 | overflow: visible; 54 | margin: auto; 55 | } 56 | .reveal { 57 | width: auto !important; 58 | height: auto !important; 59 | overflow: hidden !important; 60 | } 61 | .reveal .slides { 62 | position: static; 63 | width: 100%; 64 | height: auto; 65 | 66 | left: auto; 67 | top: auto; 68 | margin: 0 !important; 69 | padding: 0 !important; 70 | 71 | overflow: visible; 72 | display: block; 73 | 74 | -webkit-perspective: none; 75 | -moz-perspective: none; 76 | -ms-perspective: none; 77 | perspective: none; 78 | 79 | -webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */ 80 | -moz-perspective-origin: 50% 50%; 81 | -ms-perspective-origin: 50% 50%; 82 | perspective-origin: 50% 50%; 83 | } 84 | 85 | .reveal .slides section { 86 | page-break-after: always !important; 87 | 88 | visibility: visible !important; 89 | position: relative !important; 90 | display: block !important; 91 | position: relative !important; 92 | 93 | margin: 0 !important; 94 | padding: 0 !important; 95 | box-sizing: border-box !important; 96 | min-height: 1px; 97 | 98 | opacity: 1 !important; 99 | 100 | -webkit-transform-style: flat !important; 101 | -moz-transform-style: flat !important; 102 | -ms-transform-style: flat !important; 103 | transform-style: flat !important; 104 | 105 | -webkit-transform: none !important; 106 | -moz-transform: none !important; 107 | -ms-transform: none !important; 108 | transform: none !important; 109 | } 110 | 111 | .reveal section.stack { 112 | margin: 0 !important; 113 | padding: 0 !important; 114 | page-break-after: avoid !important; 115 | height: auto !important; 116 | min-height: auto !important; 117 | } 118 | 119 | .reveal img { 120 | box-shadow: none; 121 | } 122 | 123 | .reveal .roll { 124 | overflow: visible; 125 | line-height: 1em; 126 | } 127 | 128 | /* Slide backgrounds are placed inside of their slide when exporting to PDF */ 129 | .reveal section .slide-background { 130 | display: block !important; 131 | position: absolute; 132 | top: 0; 133 | left: 0; 134 | width: 100%; 135 | z-index: -1; 136 | } 137 | 138 | /* All elements should be above the slide-background */ 139 | .reveal section>* { 140 | position: relative; 141 | z-index: 1; 142 | } 143 | 144 | /* Display slide speaker notes when 'showNotes' is enabled */ 145 | .reveal .speaker-notes-pdf { 146 | display: block; 147 | width: 100%; 148 | max-height: none; 149 | left: auto; 150 | top: auto; 151 | z-index: 100; 152 | } 153 | 154 | /* Display slide numbers when 'slideNumber' is enabled */ 155 | .reveal .slide-number-pdf { 156 | display: block; 157 | position: absolute; 158 | font-size: 14px; 159 | } 160 | 161 | -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/README.md: -------------------------------------------------------------------------------- 1 | ## Dependencies 2 | 3 | Themes are written using Sass to keep things modular and reduce the need for repeated selectors across files. Make sure that you have the reveal.js development environment including the Grunt dependencies installed before proceding: https://github.com/hakimel/reveal.js#full-setup 4 | 5 | ## Creating a Theme 6 | 7 | To create your own theme, start by duplicating a ```.scss``` file in [/css/theme/source](https://github.com/hakimel/reveal.js/blob/master/css/theme/source). It will be automatically compiled by Grunt from Sass to CSS (see the [Gruntfile](https://github.com/hakimel/reveal.js/blob/master/Gruntfile.js)) when you run `grunt css-themes`. 8 | 9 | Each theme file does four things in the following order: 10 | 11 | 1. **Include [/css/theme/template/mixins.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/mixins.scss)** 12 | Shared utility functions. 13 | 14 | 2. **Include [/css/theme/template/settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss)** 15 | Declares a set of custom variables that the template file (step 4) expects. Can be overridden in step 3. 16 | 17 | 3. **Override** 18 | This is where you override the default theme. Either by specifying variables (see [settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss) for reference) or by adding any selectors and styles you please. 19 | 20 | 4. **Include [/css/theme/template/theme.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/theme.scss)** 21 | The template theme file which will generate final CSS output based on the currently defined variables. 22 | -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/source/beige.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Beige theme for reveal.js. 3 | * 4 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 5 | */ 6 | 7 | 8 | // Default mixins and settings ----------------- 9 | @import "../template/mixins"; 10 | @import "../template/settings"; 11 | // --------------------------------------------- 12 | 13 | 14 | 15 | // Include theme-specific fonts 16 | @import url(../../lib/font/league-gothic/league-gothic.css); 17 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 18 | 19 | 20 | // Override theme settings (see ../template/settings.scss) 21 | $mainColor: #333; 22 | $headingColor: #333; 23 | $headingTextShadow: none; 24 | $backgroundColor: #f7f3de; 25 | $linkColor: #8b743d; 26 | $linkColorHover: lighten( $linkColor, 20% ); 27 | $selectionBackgroundColor: rgba(79, 64, 28, 0.99); 28 | $heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); 29 | 30 | // Background generator 31 | @mixin bodyBackground() { 32 | @include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) ); 33 | } 34 | 35 | 36 | 37 | // Theme template ------------------------------ 38 | @import "../template/theme"; 39 | // --------------------------------------------- -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/source/black.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Black theme for reveal.js. This is the opposite of the 'white' theme. 3 | * 4 | * Copyright (C) 2015 Hakim El Hattab, http://hakim.se 5 | */ 6 | 7 | 8 | // Default mixins and settings ----------------- 9 | @import "../template/mixins"; 10 | @import "../template/settings"; 11 | // --------------------------------------------- 12 | 13 | 14 | // Include theme-specific fonts 15 | @import url(../../lib/font/source-sans-pro/source-sans-pro.css); 16 | 17 | 18 | // Override theme settings (see ../template/settings.scss) 19 | $backgroundColor: #222; 20 | 21 | $mainColor: #fff; 22 | $headingColor: #fff; 23 | 24 | $mainFontSize: 38px; 25 | $mainFont: 'Source Sans Pro', Helvetica, sans-serif; 26 | $headingFont: 'Source Sans Pro', Helvetica, sans-serif; 27 | $headingTextShadow: none; 28 | $headingLetterSpacing: normal; 29 | $headingTextTransform: uppercase; 30 | $headingFontWeight: 600; 31 | $linkColor: #42affa; 32 | $linkColorHover: lighten( $linkColor, 15% ); 33 | $selectionBackgroundColor: lighten( $linkColor, 25% ); 34 | 35 | $heading1Size: 2.5em; 36 | $heading2Size: 1.6em; 37 | $heading3Size: 1.3em; 38 | $heading4Size: 1.0em; 39 | 40 | section.has-light-background { 41 | &, h1, h2, h3, h4, h5, h6 { 42 | color: #222; 43 | } 44 | } 45 | 46 | 47 | // Theme template ------------------------------ 48 | @import "../template/theme"; 49 | // --------------------------------------------- -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/source/blood.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Blood theme for reveal.js 3 | * Author: Walther http://github.com/Walther 4 | * 5 | * Designed to be used with highlight.js theme 6 | * "monokai_sublime.css" available from 7 | * https://github.com/isagalaev/highlight.js/ 8 | * 9 | * For other themes, change $codeBackground accordingly. 10 | * 11 | */ 12 | 13 | // Default mixins and settings ----------------- 14 | @import "../template/mixins"; 15 | @import "../template/settings"; 16 | // --------------------------------------------- 17 | 18 | // Include theme-specific fonts 19 | 20 | @import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic); 21 | 22 | // Colors used in the theme 23 | $blood: #a23; 24 | $coal: #222; 25 | $codeBackground: #23241f; 26 | 27 | $backgroundColor: $coal; 28 | 29 | // Main text 30 | $mainFont: Ubuntu, 'sans-serif'; 31 | $mainFontSize: 36px; 32 | $mainColor: #eee; 33 | 34 | // Headings 35 | $headingFont: Ubuntu, 'sans-serif'; 36 | $headingTextShadow: 2px 2px 2px $coal; 37 | 38 | // h1 shadow, borrowed humbly from 39 | // (c) Default theme by Hakim El Hattab 40 | $heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); 41 | 42 | // Links 43 | $linkColor: $blood; 44 | $linkColorHover: lighten( $linkColor, 20% ); 45 | 46 | // Text selection 47 | $selectionBackgroundColor: $blood; 48 | $selectionColor: #fff; 49 | 50 | 51 | // Theme template ------------------------------ 52 | @import "../template/theme"; 53 | // --------------------------------------------- 54 | 55 | // some overrides after theme template import 56 | 57 | .reveal p { 58 | font-weight: 300; 59 | text-shadow: 1px 1px $coal; 60 | } 61 | 62 | .reveal h1, 63 | .reveal h2, 64 | .reveal h3, 65 | .reveal h4, 66 | .reveal h5, 67 | .reveal h6 { 68 | font-weight: 700; 69 | } 70 | 71 | .reveal p code { 72 | background-color: $codeBackground; 73 | display: inline-block; 74 | border-radius: 7px; 75 | } 76 | 77 | .reveal small code { 78 | vertical-align: baseline; 79 | } -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/source/league.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * League theme for reveal.js. 3 | * 4 | * This was the default theme pre-3.0.0. 5 | * 6 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 7 | */ 8 | 9 | 10 | // Default mixins and settings ----------------- 11 | @import "../template/mixins"; 12 | @import "../template/settings"; 13 | // --------------------------------------------- 14 | 15 | 16 | 17 | // Include theme-specific fonts 18 | @import url(../../lib/font/league-gothic/league-gothic.css); 19 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 20 | 21 | // Override theme settings (see ../template/settings.scss) 22 | $headingTextShadow: 0px 0px 6px rgba(0,0,0,0.2); 23 | $heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); 24 | 25 | // Background generator 26 | @mixin bodyBackground() { 27 | @include radial-gradient( rgba(28,30,32,1), rgba(85,90,95,1) ); 28 | } 29 | 30 | 31 | 32 | // Theme template ------------------------------ 33 | @import "../template/theme"; 34 | // --------------------------------------------- -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/source/moon.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Solarized Dark theme for reveal.js. 3 | * Author: Achim Staebler 4 | */ 5 | 6 | 7 | // Default mixins and settings ----------------- 8 | @import "../template/mixins"; 9 | @import "../template/settings"; 10 | // --------------------------------------------- 11 | 12 | 13 | 14 | // Include theme-specific fonts 15 | @import url(../../lib/font/league-gothic/league-gothic.css); 16 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 17 | 18 | /** 19 | * Solarized colors by Ethan Schoonover 20 | */ 21 | html * { 22 | color-profile: sRGB; 23 | rendering-intent: auto; 24 | } 25 | 26 | // Solarized colors 27 | $base03: #002b36; 28 | $base02: #073642; 29 | $base01: #586e75; 30 | $base00: #657b83; 31 | $base0: #839496; 32 | $base1: #93a1a1; 33 | $base2: #eee8d5; 34 | $base3: #fdf6e3; 35 | $yellow: #b58900; 36 | $orange: #cb4b16; 37 | $red: #dc322f; 38 | $magenta: #d33682; 39 | $violet: #6c71c4; 40 | $blue: #268bd2; 41 | $cyan: #2aa198; 42 | $green: #859900; 43 | 44 | // Override theme settings (see ../template/settings.scss) 45 | $mainColor: $base1; 46 | $headingColor: $base2; 47 | $headingTextShadow: none; 48 | $backgroundColor: $base03; 49 | $linkColor: $blue; 50 | $linkColorHover: lighten( $linkColor, 20% ); 51 | $selectionBackgroundColor: $magenta; 52 | 53 | 54 | 55 | // Theme template ------------------------------ 56 | @import "../template/theme"; 57 | // --------------------------------------------- 58 | -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/source/night.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Black theme for reveal.js. 3 | * 4 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 5 | */ 6 | 7 | 8 | // Default mixins and settings ----------------- 9 | @import "../template/mixins"; 10 | @import "../template/settings"; 11 | // --------------------------------------------- 12 | 13 | 14 | // Include theme-specific fonts 15 | @import url(https://fonts.googleapis.com/css?family=Montserrat:700); 16 | @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic); 17 | 18 | 19 | // Override theme settings (see ../template/settings.scss) 20 | $backgroundColor: #111; 21 | 22 | $mainFont: 'Open Sans', sans-serif; 23 | $linkColor: #e7ad52; 24 | $linkColorHover: lighten( $linkColor, 20% ); 25 | $headingFont: 'Montserrat', Impact, sans-serif; 26 | $headingTextShadow: none; 27 | $headingLetterSpacing: -0.03em; 28 | $headingTextTransform: none; 29 | $selectionBackgroundColor: #e7ad52; 30 | $mainFontSize: 30px; 31 | 32 | 33 | // Theme template ------------------------------ 34 | @import "../template/theme"; 35 | // --------------------------------------------- -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/source/serif.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple theme for reveal.js presentations, similar 3 | * to the default theme. The accent color is brown. 4 | * 5 | * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed. 6 | */ 7 | 8 | 9 | // Default mixins and settings ----------------- 10 | @import "../template/mixins"; 11 | @import "../template/settings"; 12 | // --------------------------------------------- 13 | 14 | 15 | 16 | // Override theme settings (see ../template/settings.scss) 17 | $mainFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; 18 | $mainColor: #000; 19 | $headingFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; 20 | $headingColor: #383D3D; 21 | $headingTextShadow: none; 22 | $headingTextTransform: none; 23 | $backgroundColor: #F0F1EB; 24 | $linkColor: #51483D; 25 | $linkColorHover: lighten( $linkColor, 20% ); 26 | $selectionBackgroundColor: #26351C; 27 | 28 | .reveal a { 29 | line-height: 1.3em; 30 | } 31 | 32 | 33 | // Theme template ------------------------------ 34 | @import "../template/theme"; 35 | // --------------------------------------------- 36 | -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/source/simple.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple theme for reveal.js presentations, similar 3 | * to the default theme. The accent color is darkblue. 4 | * 5 | * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed. 6 | * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 7 | */ 8 | 9 | 10 | // Default mixins and settings ----------------- 11 | @import "../template/mixins"; 12 | @import "../template/settings"; 13 | // --------------------------------------------- 14 | 15 | 16 | 17 | // Include theme-specific fonts 18 | @import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700); 19 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 20 | 21 | 22 | // Override theme settings (see ../template/settings.scss) 23 | $mainFont: 'Lato', sans-serif; 24 | $mainColor: #000; 25 | $headingFont: 'News Cycle', Impact, sans-serif; 26 | $headingColor: #000; 27 | $headingTextShadow: none; 28 | $headingTextTransform: none; 29 | $backgroundColor: #fff; 30 | $linkColor: #00008B; 31 | $linkColorHover: lighten( $linkColor, 20% ); 32 | $selectionBackgroundColor: rgba(0, 0, 0, 0.99); 33 | 34 | 35 | 36 | // Theme template ------------------------------ 37 | @import "../template/theme"; 38 | // --------------------------------------------- -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/source/sky.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Sky theme for reveal.js. 3 | * 4 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 5 | */ 6 | 7 | 8 | // Default mixins and settings ----------------- 9 | @import "../template/mixins"; 10 | @import "../template/settings"; 11 | // --------------------------------------------- 12 | 13 | 14 | 15 | // Include theme-specific fonts 16 | @import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic); 17 | @import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700); 18 | 19 | 20 | // Override theme settings (see ../template/settings.scss) 21 | $mainFont: 'Open Sans', sans-serif; 22 | $mainColor: #333; 23 | $headingFont: 'Quicksand', sans-serif; 24 | $headingColor: #333; 25 | $headingLetterSpacing: -0.08em; 26 | $headingTextShadow: none; 27 | $backgroundColor: #f7fbfc; 28 | $linkColor: #3b759e; 29 | $linkColorHover: lighten( $linkColor, 20% ); 30 | $selectionBackgroundColor: #134674; 31 | 32 | // Fix links so they are not cut off 33 | .reveal a { 34 | line-height: 1.3em; 35 | } 36 | 37 | // Background generator 38 | @mixin bodyBackground() { 39 | @include radial-gradient( #add9e4, #f7fbfc ); 40 | } 41 | 42 | 43 | 44 | // Theme template ------------------------------ 45 | @import "../template/theme"; 46 | // --------------------------------------------- 47 | -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/source/solarized.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Solarized Light theme for reveal.js. 3 | * Author: Achim Staebler 4 | */ 5 | 6 | 7 | // Default mixins and settings ----------------- 8 | @import "../template/mixins"; 9 | @import "../template/settings"; 10 | // --------------------------------------------- 11 | 12 | 13 | 14 | // Include theme-specific fonts 15 | @import url(../../lib/font/league-gothic/league-gothic.css); 16 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 17 | 18 | 19 | /** 20 | * Solarized colors by Ethan Schoonover 21 | */ 22 | html * { 23 | color-profile: sRGB; 24 | rendering-intent: auto; 25 | } 26 | 27 | // Solarized colors 28 | $base03: #002b36; 29 | $base02: #073642; 30 | $base01: #586e75; 31 | $base00: #657b83; 32 | $base0: #839496; 33 | $base1: #93a1a1; 34 | $base2: #eee8d5; 35 | $base3: #fdf6e3; 36 | $yellow: #b58900; 37 | $orange: #cb4b16; 38 | $red: #dc322f; 39 | $magenta: #d33682; 40 | $violet: #6c71c4; 41 | $blue: #268bd2; 42 | $cyan: #2aa198; 43 | $green: #859900; 44 | 45 | // Override theme settings (see ../template/settings.scss) 46 | $mainColor: $base00; 47 | $headingColor: $base01; 48 | $headingTextShadow: none; 49 | $backgroundColor: $base3; 50 | $linkColor: $blue; 51 | $linkColorHover: lighten( $linkColor, 20% ); 52 | $selectionBackgroundColor: $magenta; 53 | 54 | // Background generator 55 | // @mixin bodyBackground() { 56 | // @include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) ); 57 | // } 58 | 59 | 60 | 61 | // Theme template ------------------------------ 62 | @import "../template/theme"; 63 | // --------------------------------------------- 64 | -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/source/white.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * White theme for reveal.js. This is the opposite of the 'black' theme. 3 | * 4 | * Copyright (C) 2015 Hakim El Hattab, http://hakim.se 5 | */ 6 | 7 | 8 | // Default mixins and settings ----------------- 9 | @import "../template/mixins"; 10 | @import "../template/settings"; 11 | // --------------------------------------------- 12 | 13 | 14 | // Include theme-specific fonts 15 | @import url(../../lib/font/source-sans-pro/source-sans-pro.css); 16 | 17 | 18 | // Override theme settings (see ../template/settings.scss) 19 | $backgroundColor: #fff; 20 | 21 | $mainColor: #222; 22 | $headingColor: #222; 23 | 24 | $mainFontSize: 38px; 25 | $mainFont: 'Source Sans Pro', Helvetica, sans-serif; 26 | $headingFont: 'Source Sans Pro', Helvetica, sans-serif; 27 | $headingTextShadow: none; 28 | $headingLetterSpacing: normal; 29 | $headingTextTransform: uppercase; 30 | $headingFontWeight: 600; 31 | $linkColor: #2a76dd; 32 | $linkColorHover: lighten( $linkColor, 15% ); 33 | $selectionBackgroundColor: lighten( $linkColor, 25% ); 34 | 35 | $heading1Size: 2.5em; 36 | $heading2Size: 1.6em; 37 | $heading3Size: 1.3em; 38 | $heading4Size: 1.0em; 39 | 40 | section.has-dark-background { 41 | &, h1, h2, h3, h4, h5, h6 { 42 | color: #fff; 43 | } 44 | } 45 | 46 | 47 | // Theme template ------------------------------ 48 | @import "../template/theme"; 49 | // --------------------------------------------- -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/template/mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin vertical-gradient( $top, $bottom ) { 2 | background: $top; 3 | background: -moz-linear-gradient( top, $top 0%, $bottom 100% ); 4 | background: -webkit-gradient( linear, left top, left bottom, color-stop(0%,$top), color-stop(100%,$bottom) ); 5 | background: -webkit-linear-gradient( top, $top 0%, $bottom 100% ); 6 | background: -o-linear-gradient( top, $top 0%, $bottom 100% ); 7 | background: -ms-linear-gradient( top, $top 0%, $bottom 100% ); 8 | background: linear-gradient( top, $top 0%, $bottom 100% ); 9 | } 10 | 11 | @mixin horizontal-gradient( $top, $bottom ) { 12 | background: $top; 13 | background: -moz-linear-gradient( left, $top 0%, $bottom 100% ); 14 | background: -webkit-gradient( linear, left top, right top, color-stop(0%,$top), color-stop(100%,$bottom) ); 15 | background: -webkit-linear-gradient( left, $top 0%, $bottom 100% ); 16 | background: -o-linear-gradient( left, $top 0%, $bottom 100% ); 17 | background: -ms-linear-gradient( left, $top 0%, $bottom 100% ); 18 | background: linear-gradient( left, $top 0%, $bottom 100% ); 19 | } 20 | 21 | @mixin radial-gradient( $outer, $inner, $type: circle ) { 22 | background: $outer; 23 | background: -moz-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); 24 | background: -webkit-gradient( radial, center center, 0px, center center, 100%, color-stop(0%,$inner), color-stop(100%,$outer) ); 25 | background: -webkit-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); 26 | background: -o-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); 27 | background: -ms-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); 28 | background: radial-gradient( center, $type cover, $inner 0%, $outer 100% ); 29 | } -------------------------------------------------------------------------------- /talks/ffi/presentation/css/theme/template/settings.scss: -------------------------------------------------------------------------------- 1 | // Base settings for all themes that can optionally be 2 | // overridden by the super-theme 3 | 4 | // Background of the presentation 5 | $backgroundColor: #2b2b2b; 6 | 7 | // Primary/body text 8 | $mainFont: 'Lato', sans-serif; 9 | $mainFontSize: 36px; 10 | $mainColor: #eee; 11 | 12 | // Vertical spacing between blocks of text 13 | $blockMargin: 20px; 14 | 15 | // Headings 16 | $headingMargin: 0 0 $blockMargin 0; 17 | $headingFont: 'League Gothic', Impact, sans-serif; 18 | $headingColor: #eee; 19 | $headingLineHeight: 1.2; 20 | $headingLetterSpacing: normal; 21 | $headingTextTransform: uppercase; 22 | $headingTextShadow: none; 23 | $headingFontWeight: normal; 24 | $heading1TextShadow: $headingTextShadow; 25 | 26 | $heading1Size: 3.77em; 27 | $heading2Size: 2.11em; 28 | $heading3Size: 1.55em; 29 | $heading4Size: 1.00em; 30 | 31 | // Links and actions 32 | $linkColor: #13DAEC; 33 | $linkColorHover: lighten( $linkColor, 20% ); 34 | 35 | // Text selection 36 | $selectionBackgroundColor: #FF5E99; 37 | $selectionColor: #fff; 38 | 39 | // Generates the presentation background, can be overridden 40 | // to return a background image or gradient 41 | @mixin bodyBackground() { 42 | background: $backgroundColor; 43 | } -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/css/zenburn.css: -------------------------------------------------------------------------------- 1 | /* 2 | Zenburn style from voldmar.ru (c) Vladimir Epifanov 3 | based on dark.css by Ivan Sagalaev 4 | */ 5 | 6 | .hljs { 7 | display: block; 8 | overflow-x: auto; 9 | padding: 0.5em; 10 | background: #3f3f3f; 11 | color: #dcdcdc; 12 | -webkit-text-size-adjust: none; 13 | } 14 | 15 | .hljs-keyword, 16 | .hljs-tag, 17 | .css .hljs-class, 18 | .css .hljs-id, 19 | .lisp .hljs-title, 20 | .nginx .hljs-title, 21 | .hljs-request, 22 | .hljs-status, 23 | .clojure .hljs-attribute { 24 | color: #e3ceab; 25 | } 26 | 27 | .django .hljs-template_tag, 28 | .django .hljs-variable, 29 | .django .hljs-filter .hljs-argument { 30 | color: #dcdcdc; 31 | } 32 | 33 | .hljs-number, 34 | .hljs-date { 35 | color: #8cd0d3; 36 | } 37 | 38 | .dos .hljs-envvar, 39 | .dos .hljs-stream, 40 | .hljs-variable, 41 | .apache .hljs-sqbracket, 42 | .hljs-name { 43 | color: #efdcbc; 44 | } 45 | 46 | .dos .hljs-flow, 47 | .diff .hljs-change, 48 | .python .exception, 49 | .python .hljs-built_in, 50 | .hljs-literal, 51 | .tex .hljs-special { 52 | color: #efefaf; 53 | } 54 | 55 | .diff .hljs-chunk, 56 | .hljs-subst { 57 | color: #8f8f8f; 58 | } 59 | 60 | .dos .hljs-keyword, 61 | .hljs-decorator, 62 | .hljs-title, 63 | .hljs-type, 64 | .diff .hljs-header, 65 | .ruby .hljs-class .hljs-parent, 66 | .apache .hljs-tag, 67 | .nginx .hljs-built_in, 68 | .tex .hljs-command, 69 | .hljs-prompt { 70 | color: #efef8f; 71 | } 72 | 73 | .dos .hljs-winutils, 74 | .ruby .hljs-symbol, 75 | .ruby .hljs-symbol .hljs-string, 76 | .ruby .hljs-string { 77 | color: #dca3a3; 78 | } 79 | 80 | .diff .hljs-deletion, 81 | .hljs-string, 82 | .hljs-tag .hljs-value, 83 | .hljs-preprocessor, 84 | .hljs-pragma, 85 | .hljs-built_in, 86 | .smalltalk .hljs-class, 87 | .smalltalk .hljs-localvars, 88 | .smalltalk .hljs-array, 89 | .css .hljs-rule .hljs-value, 90 | .hljs-attr_selector, 91 | .hljs-pseudo, 92 | .apache .hljs-cbracket, 93 | .tex .hljs-formula, 94 | .coffeescript .hljs-attribute { 95 | color: #cc9393; 96 | } 97 | 98 | .hljs-shebang, 99 | .diff .hljs-addition, 100 | .hljs-comment, 101 | .hljs-annotation, 102 | .hljs-pi, 103 | .hljs-doctype { 104 | color: #7f9f7f; 105 | } 106 | 107 | .coffeescript .javascript, 108 | .javascript .xml, 109 | .tex .hljs-formula, 110 | .xml .javascript, 111 | .xml .vbscript, 112 | .xml .css, 113 | .xml .hljs-cdata { 114 | opacity: 0.5; 115 | } -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/league-gothic/LICENSE: -------------------------------------------------------------------------------- 1 | SIL Open Font License (OFL) 2 | http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL 3 | -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/league-gothic/league-gothic.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'League Gothic'; 3 | src: url('league-gothic.eot'); 4 | src: url('league-gothic.eot?#iefix') format('embedded-opentype'), 5 | url('league-gothic.woff') format('woff'), 6 | url('league-gothic.ttf') format('truetype'); 7 | 8 | font-weight: normal; 9 | font-style: normal; 10 | } -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/league-gothic/league-gothic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/league-gothic/league-gothic.eot -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/league-gothic/league-gothic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/league-gothic/league-gothic.ttf -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/league-gothic/league-gothic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/league-gothic/league-gothic.woff -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/LICENSE: -------------------------------------------------------------------------------- 1 | SIL Open Font License 2 | 3 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. 4 | 5 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 6 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL 7 | 8 | —————————————————————————————- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | —————————————————————————————- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. 14 | 15 | The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. 16 | 17 | DEFINITIONS 18 | “Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. 19 | 20 | “Reserved Font Name” refers to any names specified as such after the copyright statement(s). 21 | 22 | “Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s). 23 | 24 | “Modified Version” refers to any derivative made by adding to, deleting, or substituting—in part or in whole—any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. 25 | 26 | “Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. 27 | 28 | PERMISSION & CONDITIONS 29 | Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 30 | 31 | 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 32 | 33 | 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 34 | 35 | 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 36 | 37 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 38 | 39 | 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. 40 | 41 | TERMINATION 42 | This license becomes null and void if any of the above conditions are not met. 43 | 44 | DISCLAIMER 45 | THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-italic.eot -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-italic.ttf -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-italic.woff -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-regular.eot -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-regular.ttf -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-regular.woff -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibold.eot -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibold.ttf -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibold.woff -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibolditalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibolditalic.eot -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibolditalic.ttf -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro-semibolditalic.woff -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/font/source-sans-pro/source-sans-pro.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Source Sans Pro'; 3 | src: url('source-sans-pro-regular.eot'); 4 | src: url('source-sans-pro-regular.eot?#iefix') format('embedded-opentype'), 5 | url('source-sans-pro-regular.woff') format('woff'), 6 | url('source-sans-pro-regular.ttf') format('truetype'); 7 | font-weight: normal; 8 | font-style: normal; 9 | } 10 | 11 | @font-face { 12 | font-family: 'Source Sans Pro'; 13 | src: url('source-sans-pro-italic.eot'); 14 | src: url('source-sans-pro-italic.eot?#iefix') format('embedded-opentype'), 15 | url('source-sans-pro-italic.woff') format('woff'), 16 | url('source-sans-pro-italic.ttf') format('truetype'); 17 | font-weight: normal; 18 | font-style: italic; 19 | } 20 | 21 | @font-face { 22 | font-family: 'Source Sans Pro'; 23 | src: url('source-sans-pro-semibold.eot'); 24 | src: url('source-sans-pro-semibold.eot?#iefix') format('embedded-opentype'), 25 | url('source-sans-pro-semibold.woff') format('woff'), 26 | url('source-sans-pro-semibold.ttf') format('truetype'); 27 | font-weight: 600; 28 | font-style: normal; 29 | } 30 | 31 | @font-face { 32 | font-family: 'Source Sans Pro'; 33 | src: url('source-sans-pro-semibolditalic.eot'); 34 | src: url('source-sans-pro-semibolditalic.eot?#iefix') format('embedded-opentype'), 35 | url('source-sans-pro-semibolditalic.woff') format('woff'), 36 | url('source-sans-pro-semibolditalic.ttf') format('truetype'); 37 | font-weight: 600; 38 | font-style: italic; 39 | } -------------------------------------------------------------------------------- /talks/ffi/presentation/lib/js/classList.js: -------------------------------------------------------------------------------- 1 | /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/ 2 | if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p 3 | Copyright Tero Piirainen (tipiirai) 4 | License MIT / http://bit.ly/mit-license 5 | Version 0.96 6 | 7 | http://headjs.com 8 | */(function(a){function z(){d||(d=!0,s(e,function(a){p(a)}))}function y(c,d){var e=a.createElement("script");e.type="text/"+(c.type||"javascript"),e.src=c.src||c,e.async=!1,e.onreadystatechange=e.onload=function(){var a=e.readyState;!d.done&&(!a||/loaded|complete/.test(a))&&(d.done=!0,d())},(a.body||b).appendChild(e)}function x(a,b){if(a.state==o)return b&&b();if(a.state==n)return k.ready(a.name,b);if(a.state==m)return a.onpreload.push(function(){x(a,b)});a.state=n,y(a.url,function(){a.state=o,b&&b(),s(g[a.name],function(a){p(a)}),u()&&d&&s(g.ALL,function(a){p(a)})})}function w(a,b){a.state===undefined&&(a.state=m,a.onpreload=[],y({src:a.url,type:"cache"},function(){v(a)}))}function v(a){a.state=l,s(a.onpreload,function(a){a.call()})}function u(a){a=a||h;var b;for(var c in a){if(a.hasOwnProperty(c)&&a[c].state!=o)return!1;b=!0}return b}function t(a){return Object.prototype.toString.call(a)=="[object Function]"}function s(a,b){if(!!a){typeof a=="object"&&(a=[].slice.call(a));for(var c=0;c 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Markdown Demo 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 | 21 | 22 |
23 | 24 | 25 |
26 | 36 |
37 | 38 | 39 |
40 | 54 |
55 | 56 | 57 |
58 | 69 |
70 | 71 | 72 |
73 | 77 |
78 | 79 | 80 |
81 | 86 |
87 | 88 | 89 |
90 | 100 |
101 | 102 |
103 |
104 | 105 | 106 | 107 | 108 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /talks/ffi/presentation/plugin/markdown/example.md: -------------------------------------------------------------------------------- 1 | # Markdown Demo 2 | 3 | 4 | 5 | ## External 1.1 6 | 7 | Content 1.1 8 | 9 | Note: This will only appear in the speaker notes window. 10 | 11 | 12 | ## External 1.2 13 | 14 | Content 1.2 15 | 16 | 17 | 18 | ## External 2 19 | 20 | Content 2.1 21 | 22 | 23 | 24 | ## External 3.1 25 | 26 | Content 3.1 27 | 28 | 29 | ## External 3.2 30 | 31 | Content 3.2 32 | -------------------------------------------------------------------------------- /talks/ffi/presentation/plugin/math/math.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A plugin which enables rendering of math equations inside 3 | * of reveal.js slides. Essentially a thin wrapper for MathJax. 4 | * 5 | * @author Hakim El Hattab 6 | */ 7 | var RevealMath = window.RevealMath || (function(){ 8 | 9 | var options = Reveal.getConfig().math || {}; 10 | options.mathjax = options.mathjax || 'https://cdn.mathjax.org/mathjax/latest/MathJax.js'; 11 | options.config = options.config || 'TeX-AMS_HTML-full'; 12 | 13 | loadScript( options.mathjax + '?config=' + options.config, function() { 14 | 15 | MathJax.Hub.Config({ 16 | messageStyle: 'none', 17 | tex2jax: { 18 | inlineMath: [['$','$'],['\\(','\\)']] , 19 | skipTags: ['script','noscript','style','textarea','pre'] 20 | }, 21 | skipStartupTypeset: true 22 | }); 23 | 24 | // Typeset followed by an immediate reveal.js layout since 25 | // the typesetting process could affect slide height 26 | MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] ); 27 | MathJax.Hub.Queue( Reveal.layout ); 28 | 29 | // Reprocess equations in slides when they turn visible 30 | Reveal.addEventListener( 'slidechanged', function( event ) { 31 | 32 | MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] ); 33 | 34 | } ); 35 | 36 | } ); 37 | 38 | function loadScript( url, callback ) { 39 | 40 | var head = document.querySelector( 'head' ); 41 | var script = document.createElement( 'script' ); 42 | script.type = 'text/javascript'; 43 | script.src = url; 44 | 45 | // Wrapper for callback to make sure it only fires once 46 | var finish = function() { 47 | if( typeof callback === 'function' ) { 48 | callback.call(); 49 | callback = null; 50 | } 51 | } 52 | 53 | script.onload = finish; 54 | 55 | // IE 56 | script.onreadystatechange = function() { 57 | if ( this.readyState === 'loaded' ) { 58 | finish(); 59 | } 60 | } 61 | 62 | // Normal browsers 63 | head.appendChild( script ); 64 | 65 | } 66 | 67 | })(); 68 | -------------------------------------------------------------------------------- /talks/ffi/presentation/plugin/multiplex/client.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var multiplex = Reveal.getConfig().multiplex; 3 | var socketId = multiplex.id; 4 | var socket = io.connect(multiplex.url); 5 | 6 | socket.on(multiplex.id, function(data) { 7 | // ignore data from sockets that aren't ours 8 | if (data.socketId !== socketId) { return; } 9 | if( window.location.host === 'localhost:1947' ) return; 10 | 11 | Reveal.setState(data.state); 12 | }); 13 | }()); 14 | -------------------------------------------------------------------------------- /talks/ffi/presentation/plugin/multiplex/index.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var express = require('express'); 3 | var fs = require('fs'); 4 | var io = require('socket.io'); 5 | var crypto = require('crypto'); 6 | 7 | var app = express(); 8 | var staticDir = express.static; 9 | var server = http.createServer(app); 10 | 11 | io = io(server); 12 | 13 | var opts = { 14 | port: process.env.PORT || 1948, 15 | baseDir : __dirname + '/../../' 16 | }; 17 | 18 | io.on( 'connection', function( socket ) { 19 | socket.on('multiplex-statechanged', function(data) { 20 | if (typeof data.secret == 'undefined' || data.secret == null || data.secret === '') return; 21 | if (createHash(data.secret) === data.socketId) { 22 | data.secret = null; 23 | socket.broadcast.emit(data.socketId, data); 24 | }; 25 | }); 26 | }); 27 | 28 | [ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) { 29 | app.use('/' + dir, staticDir(opts.baseDir + dir)); 30 | }); 31 | 32 | app.get("/", function(req, res) { 33 | res.writeHead(200, {'Content-Type': 'text/html'}); 34 | fs.createReadStream(opts.baseDir + '/index.html').pipe(res); 35 | }); 36 | 37 | app.get("/token", function(req,res) { 38 | var ts = new Date().getTime(); 39 | var rand = Math.floor(Math.random()*9999999); 40 | var secret = ts.toString() + rand.toString(); 41 | res.send({secret: secret, socketId: createHash(secret)}); 42 | }); 43 | 44 | var createHash = function(secret) { 45 | var cipher = crypto.createCipher('blowfish', secret); 46 | return(cipher.final('hex')); 47 | }; 48 | 49 | // Actually listen 50 | server.listen( opts.port || null ); 51 | 52 | var brown = '\033[33m', 53 | green = '\033[32m', 54 | reset = '\033[0m'; 55 | 56 | console.log( brown + "reveal.js:" + reset + " Multiplex running on port " + green + opts.port + reset ); -------------------------------------------------------------------------------- /talks/ffi/presentation/plugin/multiplex/master.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // Don't emit events from inside of notes windows 4 | if ( window.location.search.match( /receiver/gi ) ) { return; } 5 | 6 | var multiplex = Reveal.getConfig().multiplex; 7 | 8 | var socket = io.connect( multiplex.url ); 9 | 10 | function post() { 11 | 12 | var messageData = { 13 | state: Reveal.getState(), 14 | secret: multiplex.secret, 15 | socketId: multiplex.id 16 | }; 17 | 18 | socket.emit( 'multiplex-statechanged', messageData ); 19 | 20 | }; 21 | 22 | // Monitor events that trigger a change in state 23 | Reveal.addEventListener( 'slidechanged', post ); 24 | Reveal.addEventListener( 'fragmentshown', post ); 25 | Reveal.addEventListener( 'fragmenthidden', post ); 26 | Reveal.addEventListener( 'overviewhidden', post ); 27 | Reveal.addEventListener( 'overviewshown', post ); 28 | Reveal.addEventListener( 'paused', post ); 29 | Reveal.addEventListener( 'resumed', post ); 30 | 31 | }()); -------------------------------------------------------------------------------- /talks/ffi/presentation/plugin/notes-server/client.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // don't emit events from inside the previews themselves 4 | if( window.location.search.match( /receiver/gi ) ) { return; } 5 | 6 | var socket = io.connect( window.location.origin ), 7 | socketId = Math.random().toString().slice( 2 ); 8 | 9 | console.log( 'View slide notes at ' + window.location.origin + '/notes/' + socketId ); 10 | 11 | window.open( window.location.origin + '/notes/' + socketId, 'notes-' + socketId ); 12 | 13 | /** 14 | * Posts the current slide data to the notes window 15 | */ 16 | function post() { 17 | 18 | var slideElement = Reveal.getCurrentSlide(), 19 | notesElement = slideElement.querySelector( 'aside.notes' ); 20 | 21 | var messageData = { 22 | notes: '', 23 | markdown: false, 24 | socketId: socketId, 25 | state: Reveal.getState() 26 | }; 27 | 28 | // Look for notes defined in a slide attribute 29 | if( slideElement.hasAttribute( 'data-notes' ) ) { 30 | messageData.notes = slideElement.getAttribute( 'data-notes' ); 31 | } 32 | 33 | // Look for notes defined in an aside element 34 | if( notesElement ) { 35 | messageData.notes = notesElement.innerHTML; 36 | messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string'; 37 | } 38 | 39 | socket.emit( 'statechanged', messageData ); 40 | 41 | } 42 | 43 | // When a new notes window connects, post our current state 44 | socket.on( 'new-subscriber', function( data ) { 45 | post(); 46 | } ); 47 | 48 | // When the state changes from inside of the speaker view 49 | socket.on( 'statechanged-speaker', function( data ) { 50 | Reveal.setState( data.state ); 51 | } ); 52 | 53 | // Monitor events that trigger a change in state 54 | Reveal.addEventListener( 'slidechanged', post ); 55 | Reveal.addEventListener( 'fragmentshown', post ); 56 | Reveal.addEventListener( 'fragmenthidden', post ); 57 | Reveal.addEventListener( 'overviewhidden', post ); 58 | Reveal.addEventListener( 'overviewshown', post ); 59 | Reveal.addEventListener( 'paused', post ); 60 | Reveal.addEventListener( 'resumed', post ); 61 | 62 | // Post the initial state 63 | post(); 64 | 65 | }()); 66 | -------------------------------------------------------------------------------- /talks/ffi/presentation/plugin/notes-server/index.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var express = require('express'); 3 | var fs = require('fs'); 4 | var io = require('socket.io'); 5 | var _ = require('underscore'); 6 | var Mustache = require('mustache'); 7 | 8 | var app = express(); 9 | var staticDir = express.static; 10 | var server = http.createServer(app); 11 | 12 | io = io(server); 13 | 14 | var opts = { 15 | port : 1947, 16 | baseDir : __dirname + '/../../' 17 | }; 18 | 19 | io.on( 'connection', function( socket ) { 20 | 21 | socket.on( 'new-subscriber', function( data ) { 22 | socket.broadcast.emit( 'new-subscriber', data ); 23 | }); 24 | 25 | socket.on( 'statechanged', function( data ) { 26 | socket.broadcast.emit( 'statechanged', data ); 27 | }); 28 | 29 | socket.on( 'statechanged-speaker', function( data ) { 30 | socket.broadcast.emit( 'statechanged-speaker', data ); 31 | }); 32 | 33 | }); 34 | 35 | [ 'css', 'js', 'images', 'plugin', 'lib' ].forEach( function( dir ) { 36 | app.use( '/' + dir, staticDir( opts.baseDir + dir ) ); 37 | }); 38 | 39 | app.get('/', function( req, res ) { 40 | 41 | res.writeHead( 200, { 'Content-Type': 'text/html' } ); 42 | fs.createReadStream( opts.baseDir + '/index.html' ).pipe( res ); 43 | 44 | }); 45 | 46 | app.get( '/notes/:socketId', function( req, res ) { 47 | 48 | fs.readFile( opts.baseDir + 'plugin/notes-server/notes.html', function( err, data ) { 49 | res.send( Mustache.to_html( data.toString(), { 50 | socketId : req.params.socketId 51 | })); 52 | }); 53 | 54 | }); 55 | 56 | // Actually listen 57 | server.listen( opts.port || null ); 58 | 59 | var brown = '\033[33m', 60 | green = '\033[32m', 61 | reset = '\033[0m'; 62 | 63 | var slidesLocation = 'http://localhost' + ( opts.port ? ( ':' + opts.port ) : '' ); 64 | 65 | console.log( brown + 'reveal.js - Speaker Notes' + reset ); 66 | console.log( '1. Open the slides at ' + green + slidesLocation + reset ); 67 | console.log( '2. Click on the link your JS console to go to the notes page' ); 68 | console.log( '3. Advance through your slides and your notes will advance automatically' ); 69 | -------------------------------------------------------------------------------- /talks/ffi/presentation/plugin/notes/notes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Handles opening of and synchronization with the reveal.js 3 | * notes window. 4 | * 5 | * Handshake process: 6 | * 1. This window posts 'connect' to notes window 7 | * - Includes URL of presentation to show 8 | * 2. Notes window responds with 'connected' when it is available 9 | * 3. This window proceeds to send the current presentation state 10 | * to the notes window 11 | */ 12 | var RevealNotes = (function() { 13 | 14 | function openNotes() { 15 | var jsFileLocation = document.querySelector('script[src$="notes.js"]').src; // this js file path 16 | jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, ''); // the js folder path 17 | var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1100,height=700' ); 18 | 19 | /** 20 | * Connect to the notes window through a postmessage handshake. 21 | * Using postmessage enables us to work in situations where the 22 | * origins differ, such as a presentation being opened from the 23 | * file system. 24 | */ 25 | function connect() { 26 | // Keep trying to connect until we get a 'connected' message back 27 | var connectInterval = setInterval( function() { 28 | notesPopup.postMessage( JSON.stringify( { 29 | namespace: 'reveal-notes', 30 | type: 'connect', 31 | url: window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search, 32 | state: Reveal.getState() 33 | } ), '*' ); 34 | }, 500 ); 35 | 36 | window.addEventListener( 'message', function( event ) { 37 | var data = JSON.parse( event.data ); 38 | if( data && data.namespace === 'reveal-notes' && data.type === 'connected' ) { 39 | clearInterval( connectInterval ); 40 | onConnected(); 41 | } 42 | } ); 43 | } 44 | 45 | /** 46 | * Posts the current slide data to the notes window 47 | */ 48 | function post() { 49 | 50 | var slideElement = Reveal.getCurrentSlide(), 51 | notesElement = slideElement.querySelector( 'aside.notes' ); 52 | 53 | var messageData = { 54 | namespace: 'reveal-notes', 55 | type: 'state', 56 | notes: '', 57 | markdown: false, 58 | whitespace: 'normal', 59 | state: Reveal.getState() 60 | }; 61 | 62 | // Look for notes defined in a slide attribute 63 | if( slideElement.hasAttribute( 'data-notes' ) ) { 64 | messageData.notes = slideElement.getAttribute( 'data-notes' ); 65 | messageData.whitespace = 'pre-wrap'; 66 | } 67 | 68 | // Look for notes defined in an aside element 69 | if( notesElement ) { 70 | messageData.notes = notesElement.innerHTML; 71 | messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string'; 72 | } 73 | 74 | notesPopup.postMessage( JSON.stringify( messageData ), '*' ); 75 | 76 | } 77 | 78 | /** 79 | * Called once we have established a connection to the notes 80 | * window. 81 | */ 82 | function onConnected() { 83 | 84 | // Monitor events that trigger a change in state 85 | Reveal.addEventListener( 'slidechanged', post ); 86 | Reveal.addEventListener( 'fragmentshown', post ); 87 | Reveal.addEventListener( 'fragmenthidden', post ); 88 | Reveal.addEventListener( 'overviewhidden', post ); 89 | Reveal.addEventListener( 'overviewshown', post ); 90 | Reveal.addEventListener( 'paused', post ); 91 | Reveal.addEventListener( 'resumed', post ); 92 | 93 | // Post the initial state 94 | post(); 95 | 96 | } 97 | 98 | connect(); 99 | } 100 | 101 | if( !/receiver/i.test( window.location.search ) ) { 102 | 103 | // If the there's a 'notes' query set, open directly 104 | if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) { 105 | openNotes(); 106 | } 107 | 108 | // Open the notes when the 's' key is hit 109 | document.addEventListener( 'keydown', function( event ) { 110 | // Disregard the event if the target is editable or a 111 | // modifier is present 112 | if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return; 113 | 114 | // Disregard the event if keyboard is disabled 115 | if ( Reveal.getConfig().keyboard === false ) return; 116 | 117 | if( event.keyCode === 83 ) { 118 | event.preventDefault(); 119 | openNotes(); 120 | } 121 | }, false ); 122 | 123 | } 124 | 125 | return { open: openNotes }; 126 | 127 | })(); 128 | -------------------------------------------------------------------------------- /talks/ffi/presentation/plugin/print-pdf/print-pdf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * phantomjs script for printing presentations to PDF. 3 | * 4 | * Example: 5 | * phantomjs print-pdf.js "http://lab.hakim.se/reveal-js?print-pdf" reveal-demo.pdf 6 | * 7 | * By Manuel Bieh (https://github.com/manuelbieh) 8 | */ 9 | 10 | // html2pdf.js 11 | var page = new WebPage(); 12 | var system = require( 'system' ); 13 | 14 | var slideWidth = system.args[3] ? system.args[3].split( 'x' )[0] : 960; 15 | var slideHeight = system.args[3] ? system.args[3].split( 'x' )[1] : 700; 16 | 17 | page.viewportSize = { 18 | width: slideWidth, 19 | height: slideHeight 20 | }; 21 | 22 | // TODO 23 | // Something is wrong with these config values. An input 24 | // paper width of 1920px actually results in a 756px wide 25 | // PDF. 26 | page.paperSize = { 27 | width: Math.round( slideWidth * 2 ), 28 | height: Math.round( slideHeight * 2 ), 29 | border: 0 30 | }; 31 | 32 | var inputFile = system.args[1] || 'index.html?print-pdf'; 33 | var outputFile = system.args[2] || 'slides.pdf'; 34 | 35 | if( outputFile.match( /\.pdf$/gi ) === null ) { 36 | outputFile += '.pdf'; 37 | } 38 | 39 | console.log( 'Printing PDF (Paper size: '+ page.paperSize.width + 'x' + page.paperSize.height +')' ); 40 | 41 | page.open( inputFile, function( status ) { 42 | window.setTimeout( function() { 43 | console.log( 'Printed succesfully' ); 44 | page.render( outputFile ); 45 | phantom.exit(); 46 | }, 1000 ); 47 | } ); 48 | 49 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/examples/assets/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/test/examples/assets/image1.png -------------------------------------------------------------------------------- /talks/ffi/presentation/test/examples/assets/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/ffi/presentation/test/examples/assets/image2.png -------------------------------------------------------------------------------- /talks/ffi/presentation/test/examples/barebones.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Barebones 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 |
17 | 18 |
19 |

Barebones Presentation

20 |

This example contains the bare minimum includes and markup required to run a reveal.js presentation.

21 |
22 | 23 |
24 |

No Theme

25 |

There's no theme included, so it will fall back on browser defaults.

26 |
27 | 28 |
29 | 30 |
31 | 32 | 33 | 34 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/examples/embedded-media.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Embedded Media 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 | 21 |
22 |

Embedded Media Test

23 |
24 | 25 |
26 | 27 |
28 | 29 |
30 |

Empty Slide

31 |
32 | 33 |
34 | 35 |
36 | 37 | 38 | 39 | 40 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/examples/slide-backgrounds.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Slide Backgrounds 8 | 9 | 10 | 11 | 12 | 13 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |
32 |

data-background: #00ffff

33 |
34 | 35 |
36 |

data-background: #bb00bb

37 |
38 | 39 |
40 |

data-background: lightblue

41 |
42 | 43 |
44 |
45 |

data-background: #ff0000

46 |
47 |
48 |

data-background: rgba(0, 0, 0, 0.2)

49 |
50 |
51 |

data-background: salmon

52 |
53 |
54 | 55 |
56 |
57 |

Background applied to stack

58 |
59 |
60 |

Background applied to stack

61 |
62 |
63 |

Background applied to slide inside of stack

64 |
65 |
66 | 67 |
68 |

Background image

69 |
70 | 71 |
72 |
73 |

Background image

74 |
75 |
76 |

Background image

77 |
78 |
79 | 80 |
81 |

Background image

82 |
data-background-size="100px" data-background-repeat="repeat" data-background-color="#111"
83 |
84 | 85 |
86 |

Same background twice (1/2)

87 |
88 |
89 |

Same background twice (2/2)

90 |
91 | 92 |
93 |

Video background

94 |
95 | 96 |
97 |

Iframe background

98 |
99 | 100 |
101 |
102 |

Same background twice vertical (1/2)

103 |
104 |
105 |

Same background twice vertical (2/2)

106 |
107 |
108 | 109 |
110 |

Same background from horizontal to vertical (1/3)

111 |
112 |
113 |
114 |

Same background from horizontal to vertical (2/3)

115 |
116 |
117 |

Same background from horizontal to vertical (3/3)

118 |
119 |
120 | 121 |
122 | 123 |
124 | 125 | 126 | 127 | 128 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/examples/slide-transitions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Slide Transitions 8 | 9 | 10 | 11 | 21 | 22 | 23 | 24 | 25 |
26 | 27 |
28 | 29 |
30 |

Default

31 |
32 | 33 |
34 |

Default

35 |
36 | 37 |
38 |

data-transition: zoom

39 |
40 | 41 |
42 |

data-transition: zoom-in fade-out

43 |
44 | 45 |
46 |

Default

47 |
48 | 49 |
50 |

data-transition: convex

51 |
52 | 53 |
54 |

data-transition: convex-in concave-out

55 |
56 | 57 |
58 |
59 |

Default

60 |
61 |
62 |

data-transition: concave

63 |
64 |
65 |

data-transition: convex-in fade-out

66 |
67 |
68 |

Default

69 |
70 |
71 | 72 |
73 |

data-transition: none

74 |
75 | 76 |
77 |

Default

78 |
79 | 80 |
81 | 82 |
83 | 84 | 85 | 86 | 87 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/test-markdown-element-attributes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Test Markdown Element Attributes 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/test-markdown-element-attributes.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | Reveal.addEventListener( 'ready', function() { 4 | 5 | QUnit.module( 'Markdown' ); 6 | 7 | test( 'Vertical separator', function() { 8 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 4, 'found four slides' ); 9 | }); 10 | 11 | 12 | test( 'Attributes on element header in vertical slides', function() { 13 | strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' ); 14 | strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' ); 15 | }); 16 | 17 | test( 'Attributes on element paragraphs in vertical slides', function() { 18 | strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' ); 19 | }); 20 | 21 | test( 'Attributes on element list items in vertical slides', function() { 22 | strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.grow' ).length, 3, 'found a vertical slide with three list items with class fragment.grow' ); 23 | }); 24 | 25 | test( 'Attributes on element paragraphs in horizontal slides', function() { 26 | strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' ); 27 | }); 28 | test( 'Attributes on element list items in horizontal slides', function() { 29 | strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' ); 30 | }); 31 | test( 'Attributes on element list items in horizontal slides', function() { 32 | strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' ); 33 | }); 34 | 35 | test( 'Attributes on elements in vertical slides with default element attribute separator', function() { 36 | strictEqual( document.querySelectorAll( '.reveal .slides section h2.fragment.highlight-red' ).length, 2, 'found two h2 titles with fragment highlight-red in vertical slides with default element attribute separator' ); 37 | }); 38 | 39 | test( 'Attributes on elements in single slides with default element attribute separator', function() { 40 | strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-blue' ).length, 3, 'found three elements with fragment highlight-blue in single slide with default element attribute separator' ); 41 | }); 42 | 43 | } ); 44 | 45 | Reveal.initialize(); 46 | 47 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/test-markdown-slide-attributes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Test Markdown Attributes 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/test-markdown-slide-attributes.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | Reveal.addEventListener( 'ready', function() { 4 | 5 | QUnit.module( 'Markdown' ); 6 | 7 | test( 'Vertical separator', function() { 8 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 6, 'found six vertical slides' ); 9 | }); 10 | 11 | test( 'Id on slide', function() { 12 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section#slide2' ).length, 1, 'found one slide with id slide2' ); 13 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section a[href="#/slide2"]' ).length, 1, 'found one slide with a link to slide2' ); 14 | }); 15 | 16 | test( 'data-background attributes', function() { 17 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A0C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' ); 18 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#ff0000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' ); 19 | strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C6916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' ); 20 | }); 21 | 22 | test( 'data-transition attributes', function() { 23 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="zoom"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' ); 24 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="fade"]' ).length, 1, 'found one vertical slide with data-transition="fade"' ); 25 | strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="zoom"]' ).length, 1, 'found one slide with data-transition="zoom"' ); 26 | }); 27 | 28 | test( 'data-background attributes with default separator', function() { 29 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A7C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' ); 30 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#f70000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' ); 31 | strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C7916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' ); 32 | }); 33 | 34 | test( 'data-transition attributes with default separator', function() { 35 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="concave"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' ); 36 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="page"]' ).length, 1, 'found one vertical slide with data-transition="fade"' ); 37 | strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="concave"]' ).length, 1, 'found one slide with data-transition="zoom"' ); 38 | }); 39 | 40 | test( 'data-transition attributes with inline content', function() { 41 | strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#ff0000"]' ).length, 3, 'found three horizontal slides with data-background="#ff0000"' ); 42 | }); 43 | 44 | } ); 45 | 46 | Reveal.initialize(); 47 | 48 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/test-markdown.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Test Markdown 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/test-markdown.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | Reveal.addEventListener( 'ready', function() { 4 | 5 | QUnit.module( 'Markdown' ); 6 | 7 | test( 'Vertical separator', function() { 8 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' ); 9 | }); 10 | 11 | 12 | } ); 13 | 14 | Reveal.initialize(); 15 | 16 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/test-pdf.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Test PDF exports 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 | 19 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/test-pdf.js: -------------------------------------------------------------------------------- 1 | 2 | Reveal.addEventListener( 'ready', function() { 3 | 4 | // Only one test for now, we're mainly ensuring that there 5 | // are no execution errors when running PDF mode 6 | 7 | test( 'Reveal.isReady', function() { 8 | strictEqual( Reveal.isReady(), true, 'returns true' ); 9 | }); 10 | 11 | 12 | } ); 13 | 14 | Reveal.initialize({ pdf: true }); 15 | 16 | -------------------------------------------------------------------------------- /talks/ffi/presentation/test/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Tests 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /talks/ffi/programs/7.hs: -------------------------------------------------------------------------------- 1 | newtype {-# CTYPE "const char*" #-} T = T CString 2 | 3 | foreign import ccall "spiel/spiel.h m0_spiel_start" 4 | c_spiel_start :: Ptr SpielContextV 5 | -> Ptr ReqHV 6 | -> Ptr T 7 | -> CString 8 | -> IO CInt 9 | -------------------------------------------------------------------------------- /talks/ffi/programs/capi/Makefile: -------------------------------------------------------------------------------- 1 | all: test 2 | 3 | test: test.hs pi.o pi.h 4 | ghc test.hs pi.o -keep-temp 5 | 6 | pi.o: pi.c pi.h 7 | $(CC) $< -c -o $@ 8 | -------------------------------------------------------------------------------- /talks/ffi/programs/capi/pi.c: -------------------------------------------------------------------------------- 1 | #include "pi.h" 2 | 3 | int test(int x, int y) { 4 | return x * y; 5 | } 6 | -------------------------------------------------------------------------------- /talks/ffi/programs/capi/pi.h: -------------------------------------------------------------------------------- 1 | #ifndef PI__H 2 | #define PI__H 3 | 4 | const double pi = 3.14; 5 | #define pi2 3.1415; 6 | 7 | int test(int,int); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /talks/ffi/programs/capi/test.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CApiFFI #-} 2 | 3 | foreign import capi "pi.h value pi" c_pi :: Double 4 | foreign import capi "pi.h value pi2" c_pi2 :: Double 5 | foreign import capi "pi.h test" c_test :: Int -> IO Int 6 | 7 | main = do 8 | print =<< c_test 7 -- (c_pi, c_pi2) 9 | -------------------------------------------------------------------------------- /talks/ffi/programs/capi/test2.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE ForeignFunctionInterface #-} 2 | import Foreign 3 | import Foreign.C 4 | 5 | foreign import ccall "pi.h &pi" c_pi :: Ptr CDouble 6 | -- Impossible: 7 | -- foreign import ccall "pi.h &pi2" c_pi2 :: Ptr CDouble 8 | 9 | main = do 10 | print (c_pi) 11 | -------------------------------------------------------------------------------- /talks/ffi/programs/fork-on-simple.hs: -------------------------------------------------------------------------------- 1 | import Data.Foldable (forM_) 2 | import Control.Concurrent 3 | import System.Environment 4 | -- Don't do this, only for demo purposes: 5 | import Control.Exception (evaluate) 6 | import Control.DeepSeq (force) 7 | 8 | fibs :: [Integer] 9 | fibs = 0:1:zipWith (+) fibs (tail fibs) 10 | 11 | main :: IO () 12 | main = do 13 | [i,l] <- map read <$> getArgs 14 | lock <- newQSem i 15 | for [0..i] $ \z -> do 16 | waitQSem lock 17 | forkOn z $ do 18 | forM_ [0..l] $ evaluate . force . (!!) fibs 19 | signalQSem lock 20 | replicateM_ 3 $ waitQSem lock 21 | -------------------------------------------------------------------------------- /talks/ffi/programs/gperf/Makefile: -------------------------------------------------------------------------------- 1 | all: bench 2 | 3 | bench: bench.hs table.o table.2.o 4 | ghc -g -O2 $^ -o $@ 5 | 6 | table.o: table.c 7 | gcc -c -O3 $^ -o $@ 8 | 9 | table.c: words-1000.txt 10 | gperf words-1000.txt > table.c 11 | 12 | -------------------------------------------------------------------------------- /talks/ffi/programs/gperf/bench.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE GHCForeignImportPrim #-} 2 | {-# LANGUAGE MagicHash #-} 3 | {-# LANGUAGE ForeignFunctionInterface #-} 4 | {-# LANGUAGE OverloadedStrings #-} 5 | {-# LANGUAGE UnliftedFFITypes #-} 6 | import Criterion.Main 7 | 8 | import Foreign 9 | import Foreign.C 10 | import Data.ByteString (ByteString) 11 | import Data.ByteString.Unsafe (unsafeUseAsCStringLen) 12 | import GHC.Ptr 13 | import GHC.Prim 14 | import GHC.Int 15 | import GHC.Word 16 | import GHC.Types 17 | 18 | import System.IO.Unsafe (unsafeDupablePerformIO) 19 | 20 | foreign import ccall unsafe "in_word_set" c_in_word_set :: CString -> CInt -> IO CString 21 | 22 | foreign import prim "in_word_setprim1" prim_in_word_set# :: Addr# -> Int# -> Addr# 23 | 24 | inWordsSet :: ByteString -> IO Bool 25 | inWordsSet str = unsafeUseAsCStringLen str $ \(cptr, len) -> do 26 | result <- c_in_word_set cptr (fromIntegral len) 27 | return $ nullPtr /= result 28 | 29 | sumsets1 :: [ByteString] -> IO Int 30 | sumsets1 = fmap sum . mapM (fmap fromEnum . inWordsSet) 31 | 32 | sumsets2 :: [ByteString] -> IO Int 33 | sumsets2 = fmap sum . mapM (fmap fromEnum . inWordsSet1) 34 | 35 | inWordsSet1 :: ByteString -> IO Bool 36 | inWordsSet1 str = unsafeUseAsCStringLen str $ \(Ptr addr, I# len) -> do 37 | case prim_in_word_set# addr len of 38 | result -> case neAddr# nullAddr# result of 39 | 0# -> return False 40 | _ -> return True 41 | 42 | unsafeContents :: ByteString -> (CString, Int) 43 | unsafeContents str = unsafeDupablePerformIO $ unsafeUseAsCStringLen str return 44 | 45 | inWordsSet1# :: ByteString -> Int# 46 | inWordsSet1# str = case unsafeContents str of 47 | (Ptr addr, I# len) -> case prim_in_word_set# addr len of 48 | result -> neAddr# nullAddr# result 49 | 50 | sumsetsopt :: [ByteString] -> Int 51 | sumsetsopt xs = let loop# [] c = I# c 52 | loop# (y:ys) c = loop# ys (c +# (inWordsSet1# y)) 53 | in loop# xs 0# 54 | 55 | 56 | wrds = 57 | [ "abbreviating" 58 | , "abbreviation" 59 | , "abbreviations" 60 | , "a" 61 | , "abberiations" 62 | ,"a" 63 | ,"aah" 64 | ,"aahed" 65 | ,"aahing" 66 | ,"aahs" 67 | ,"aardvark" 68 | ,"aardvarks" 69 | ,"aardwolf" 70 | ,"ab" 71 | ,"abaci" 72 | ,"aback" 73 | ,"abacus" 74 | , "sdfsdfs" 75 | , "sdfsdfs" 76 | ,"abacuses" 77 | ,"abaft" 78 | ,"abalone" 79 | ,"abalones" 80 | ,"abandon" 81 | ,"abandoned" 82 | ,"abandonedly" 83 | ,"abandonee" 84 | ,"abandoner" 85 | ,"abandoners" 86 | ,"abandoning" 87 | ,"abandonment" 88 | ,"abandonments" 89 | ,"abandons" 90 | ,"abase" 91 | ,"abased" 92 | ,"abasedly" 93 | ,"abasement" 94 | ,"abaser" 95 | ,"abasers" 96 | ,"abases" 97 | ,"abash" 98 | ,"abashed" 99 | ,"abashedly" 100 | ,"abashes" 101 | ,"abashing" 102 | ,"abashment" 103 | ,"abashments" 104 | ,"abasing" 105 | ,"abatable" 106 | ,"abate" 107 | ,"abated" 108 | ,"abatement" 109 | ,"abatements" 110 | ,"abater" 111 | ,"abaters" 112 | ,"abates" 113 | ,"abating" 114 | ] 115 | 116 | main = -- do print =<< sumsets1 wrds 117 | -- print =<< sumsets2 wrds 118 | defaultMain 119 | [ bench "inWordsSet" $ nfIO $ and <$> mapM inWordsSet wrds 120 | , bench "inWordsSet1" $ nfIO $ and <$> mapM inWordsSet1 wrds 121 | , bench "sum-unsafe" $ nfIO $ sumsets1 wrds 122 | , bench "sum-prim" $ nfIO $ sumsets2 wrds 123 | , bench "sum-opt" $ nf sumsetsopt wrds 124 | ] 125 | -------------------------------------------------------------------------------- /talks/ffi/programs/rts-signal/Makefile: -------------------------------------------------------------------------------- 1 | test: test.hs bogus.o 2 | ghc --make -O2 $^ 3 | 4 | bogus.o: bogus.c 5 | $(CC) $^ -c -o $@ 6 | -------------------------------------------------------------------------------- /talks/ffi/programs/rts-signal/bogus.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int bogus() { 4 | return usleep(100000000); 5 | } 6 | -------------------------------------------------------------------------------- /talks/ffi/programs/rts-signal/bogus.h: -------------------------------------------------------------------------------- 1 | #ifndef BOGUS_H 2 | #define BOGUS_H 3 | ssize_t bogus(); 4 | #endif 5 | -------------------------------------------------------------------------------- /talks/ffi/programs/rts-signal/test.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE ForeignFunctionInterface #-} 2 | 3 | import Foreign.C 4 | import Foreign.C.Error 5 | import Control.Concurrent 6 | import Control.Monad 7 | import Data.Time 8 | 9 | foreign import ccall safe bogus :: IO CSize 10 | 11 | hsBogus :: IO Int 12 | hsBogus = fmap fromIntegral bogus 13 | 14 | main = do 15 | forkIO $ do yield 16 | print =<< getCurrentTime 17 | ret <- hsBogus 18 | print =<< getCurrentTime 19 | print ret 20 | en <- getErrno 21 | print (errnoToIOError "none" en Nothing Nothing) 22 | forever $ do putStrLn "." 23 | threadDelay 1000000 24 | -------------------------------------------------------------------------------- /talks/ffi/programs/safe-vs-unsafe-bench/Makefile: -------------------------------------------------------------------------------- 1 | all: bench bench-threaded 2 | 3 | bench: bench.hs 4 | ghc -O2 $< -o $@ 5 | 6 | bench-threaded: bench.hs 7 | ghc -O2 -threaded $< -o $@ 8 | -------------------------------------------------------------------------------- /talks/ffi/programs/safe-vs-unsafe-bench/bench.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE ForeignFunctionInterface #-} 2 | import Criterion.Main 3 | 4 | import Foreign.C 5 | import Control.Concurrent.Async 6 | 7 | foreign import ccall safe " getpid" safe_ppid :: IO CInt 8 | foreign import ccall unsafe " getpid" unsafe_ppid :: IO CInt 9 | 10 | parSafe, parUnsafe :: IO [CInt] 11 | parSafe = mapConcurrently (const safe_ppid) [0..1000] 12 | parUnsafe = mapConcurrently (const unsafe_ppid) [0..1000] 13 | 14 | main = defaultMain 15 | [ bench "safe" $ nfIO safe_ppid 16 | , bench "unsafe" $ nfIO unsafe_ppid 17 | , bench "par-safe" $ nfIO parSafe 18 | , bench "par-unsafe" $ nfIO parUnsafe 19 | ] 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /talks/ffi/programs/unsafe-bottom/Makefile: -------------------------------------------------------------------------------- 1 | runit: runit.hs bottom.o 2 | ghc $^ -o runit -threaded 3 | 4 | bottom.o: bottom.c bottom.h 5 | $(CC) $< -c -o $@ 6 | 7 | 8 | -------------------------------------------------------------------------------- /talks/ffi/programs/unsafe-bottom/bottom.c: -------------------------------------------------------------------------------- 1 | #include "bottom.h" 2 | 3 | void bottom(int i) { for(;;); }; 4 | -------------------------------------------------------------------------------- /talks/ffi/programs/unsafe-bottom/runit.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE ForeignFunctionInterface #-} 2 | import Control.Concurrent 3 | import Control.Monad 4 | import Foreign.C 5 | foreign import ccall safe " bottom" safe_bottom :: CInt -> IO () 6 | foreign import ccall unsafe " bottom" unsafe_bottom :: CInt -> IO () 7 | 8 | main :: IO () 9 | main = do 10 | lock <- newEmptyMVar 11 | forkIO $ safe_bottom 1 12 | yield 13 | print "Pass" 14 | forkIO $ do 15 | forever $ putStrLn "." >> threadDelay 1000000 16 | putMVar lock () 17 | forkOn 2 $ void $ forkOS $ yield >> unsafe_bottom 1 18 | print "Pass" 19 | takeMVar lock 20 | -------------------------------------------------------------------------------- /talks/ffi/thread-local-storage.org: -------------------------------------------------------------------------------- 1 | Thread local storage analysis. 2 | 3 | 4 | * Links 5 | 6 | ** Thread local storage vs non-blocking data structures 7 | Properties: 8 | - url:: https://software.intel.com/en-us/comment/1578348 9 | 10 | ** Use thread local storage to reduce synchronization 11 | Properties: 12 | - url:: https://software.intel.com/en-us/articles/use-thread-local-storage-to-reduce-synchronization 13 | 14 | When different threads write to the counter, they should 15 | have some blocking mechanism. As a result local storage 16 | may improve speed, by avoiding blocking code. 17 | 18 | 1. Statistical counting (perfbook) 19 | 2. Low overhead logging 20 | 3. lightweight reader writer locks 21 | 22 | -------------------------------------------------------------------------------- /talks/fpure-capabilities-final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qnikst/haskell-fun/3562c44e45f4a391a6964cb7fb54da9c22d5b2ae/talks/fpure-capabilities-final.pdf -------------------------------------------------------------------------------- /typelevel-comp/composable.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DataKinds #-} 2 | {-# LANGUAGE KindSignatures #-} 3 | {-# LANGUAGE TypeFamilies #-} 4 | {-# LANGUAGE FlexibleContexts #-} 5 | {-# LANGUAGE TypeOperators #-} 6 | {-# LANGUAGE MultiParamTypeClasses #-} 7 | {-# LANGUAGE FlexibleInstances #-} 8 | {-# LANGUAGE ConstraintKinds #-} 9 | {-# LANGUAGE ScopedTypeVariables #-} 10 | {-# LANGUAGE UndecidableInstances #-} 11 | 12 | import GHC.TypeLits 13 | import GHC.Exts (Constraint) 14 | import Data.Proxy 15 | 16 | g1 :: Integer -> Double 17 | g1 p = 1 / (2 - 2**(1/(fromIntegral p+1))) 18 | 19 | g2 :: Integer -> Double 20 | g2 p = - 2**(1/(fromIntegral p+1)) / ( 2 - 2**(1/(fromIntegral p+1))) 21 | 22 | 23 | g3 :: Integer -> Double 24 | g3 = g1 25 | -- [g1, g2, g1] 26 | 27 | -- Apply a method 28 | t :: Integer -> Double -> [Double] 29 | t p dt = map (*dt) [g1 p, g2 p, g3 p] 30 | 31 | -- Upgrade a method 32 | ut :: Integer -> [Double] -> [Double] 33 | ut p xs = xs >>= (\x -> t (p+2) x) 34 | 35 | 36 | data RK2 = RK2 37 | 38 | type family Order a :: Nat 39 | type instance Order RK2 = 2 40 | 41 | type family IsSymmetric a :: Constraint 42 | type instance IsSymmetric RK2 = () 43 | 44 | buildComposePoints :: forall p . KnownNat (Order p) 45 | => p -> Double -> [Double] 46 | buildComposePoints p dt = map (*dt) [g1 o, g2 o, g3 o] 47 | where 48 | o = natVal (Proxy :: Proxy (Order p)) 49 | 50 | buildComposePointsSym :: forall p n . (UpdateCompose (Order p + 2) n, IsSymmetric p, KnownNat (Order p), KnownNat n) 51 | => p -> Proxy n -> Double -> [Double] 52 | buildComposePointsSym p pn dt = update (Proxy :: Proxy ((Order p) + 2)) pn (buildComposePoints p dt) 53 | 54 | class UpdateCompose (k :: Nat) (v::Nat) where 55 | update :: Proxy k -> Proxy v -> [Double] -> [Double] 56 | 57 | class UpdateComposeCase (leq :: Bool) (k :: Nat) (v :: Nat) where 58 | updateCase :: Proxy leq -> Proxy k -> Proxy v -> [Double] -> [Double] 59 | 60 | instance UpdateComposeCase (k <=? v) k v => UpdateCompose k v where 61 | update = updateCase (Proxy :: Proxy (k <=? v)) 62 | 63 | instance UpdateComposeCase False k v where 64 | updateCase _ _ _ = id 65 | 66 | instance (KnownNat k, UpdateCompose (k+2) v) => UpdateComposeCase True k v where 67 | updateCase _ k v ds = update (plus2 k) v (ds >>= \x -> map (*x) [g1 o, g2 o, g3 o]) 68 | where 69 | o = natVal k 70 | plus2 :: Proxy n -> Proxy (n+2) 71 | plus2 _ = Proxy 72 | -------------------------------------------------------------------------------- /typelevel-literals/Main.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# LANGUAGE QuasiQuotes #-} 3 | {-# LANGUAGE PolyKinds #-} 4 | {-# LANGUAGE DataKinds #-} 5 | {-# LANGUAGE TypeOperators #-} 6 | 7 | import Data.Ratio (Ratio(..)) 8 | import Data.Proxy 9 | import GHC.Real (Ratio(..)) 10 | import GHC.TypeLits 11 | import Language.Haskell.TH 12 | 13 | import TypeLevelRatio 14 | import TypeLevelFloat 15 | 16 | import Data.Tagged 17 | 18 | toProxy :: Tagged n a -> Proxy n 19 | toProxy _ = Proxy 20 | 21 | mkT :: proxy n -> a -> Tagged n a 22 | mkT _ a = Tagged a 23 | 24 | useT :: (KnownNat n, Num a) => Tagged n a -> a 25 | useT t@(Tagged a) = fromIntegral (natVal (toProxy t)) + a 26 | 27 | useTF :: (KnownNat n, KnownNat m, Fractional a) => Tagged (n :%% m) a -> a 28 | useTF t@(Tagged a) = v + a 29 | where v = fromRational $ 30 | natVal (numerator $ toProxy t) :% natVal (denomenator $ toProxy t) 31 | 32 | test = mkT $(mkFloatProxy pi) 7.0 33 | 34 | {- 35 | -- *Main> mkT (Proxy::Proxy 3) 1 + mkT (Proxy::Proxy 3) 2 36 | -- Loading package tagged-0.7.2 ... linking ... done. 37 | -- Tagged 3 38 | -} 39 | 40 | (^+) :: (KnownNat n, KnownNat m) => Tagged n a -> Tagged m a -> Maybe (Tagged n a) 41 | a (^+) b = 42 | case (sameNat `on` toProxy) a b 43 | Just x -> Just (retag 44 | -------------------------------------------------------------------------------- /typelevel-literals/README.markdown: -------------------------------------------------------------------------------- 1 | A playground for working with typelevel literals 2 | ------------------------------------------------ 3 | 4 | ## Typelevel numbers 5 | Approach to write more typelevel numbers, like positive 6 | rational, positive reals. 7 | 8 | Really it's not finished, writing typelevel GCD will 9 | help a lot. 10 | 11 | Related posts: 12 | 13 | 1. http://qnikst.github.io/posts/2014-08-07-playing-with-types.html 14 | 15 | Additional problems: 16 | 17 | 1. how to write typelevel GCD. 18 | 2. or typelevel building of rational. 19 | 20 | ## Proof 21 | 22 | Approach to solve a problem in boundaries between trusted and untrusted 23 | code by giving a checking that value fits the required constraints. 24 | 25 | 26 | Related discussion (public one). 27 | 28 | 1. https://www.haskell.org/pipermail/glasgow-haskell-users/2014-November/025451.html 29 | 30 | Related post: 31 | 32 | 1. TBD 33 | -------------------------------------------------------------------------------- /typelevel-literals/TypeLevelFloat.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE PolyKinds #-} 2 | {-# LANGUAGE DataKinds #-} 3 | {-# LANGUAGE TemplateHaskell #-} 4 | {-# LANGUAGE TypeOperators #-} 5 | module TypeLevelFloat 6 | ( mkFloatProxy 7 | , mkProxy 8 | ) where 9 | 10 | import Data.Ratio 11 | import Data.Proxy 12 | import Language.Haskell.TH 13 | import GHC.Real 14 | import TypeLevelRatio 15 | import Language.Haskell.TH.Syntax 16 | import GHC.TypeLits 17 | 18 | mkFloatProxy :: RealFrac a => a -> Q Exp 19 | mkFloatProxy x = [| Proxy :: Proxy ($(nk a) :%% $(nk b)) |] 20 | where (a :% b) = toRational x 21 | nk x = sigT (litT (numTyLit x)) (ConT $ mkName "Nat") 22 | 23 | mkProxy :: Q Exp 24 | mkProxy = [| Proxy :: Proxy ($(sigT (litT (numTyLit i)) (ConT $ mkName "Nat"))) |] 25 | where i = 3 26 | -------------------------------------------------------------------------------- /typelevel-literals/TypeLevelRatio.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE PolyKinds #-} 2 | {-# LANGUAGE DataKinds #-} 3 | {-# LANGUAGE KindSignatures #-} 4 | {-# LANGUAGE TypeOperators #-} 5 | module TypeLevelRatio 6 | ( (:%%) 7 | , numerator 8 | , denomenator 9 | ) where 10 | 11 | import Data.Proxy 12 | import GHC.TypeLits 13 | 14 | data (:%%) a b 15 | 16 | -- | extract numerator type 17 | numerator :: proxy (n :%% m) -> Proxy n 18 | numerator _ = Proxy 19 | 20 | -- | Extract denomenator type 21 | denomenator :: proxy (n :%% m) -> Proxy m 22 | denomenator _ = Proxy 23 | --------------------------------------------------------------------------------