Skip to content

Instantly share code, notes, and snippets.

@edwinb
edwinb / fakechar.idr
Created August 10, 2015 13:33
Faked overloaded strings
data FakeChar = A | B | C
data ValidMyString : List Char -> Type where
VA : ValidMyString xs -> ValidMyString ('a' :: xs)
VB : ValidMyString xs -> ValidMyString ('b' :: xs)
VC : ValidMyString xs -> ValidMyString ('c' :: xs)
VNil : ValidMyString []
implicit fromString : (x : String) -> {auto p : ValidMyString (unpack x)}
-> List FakeChar
@edwinb
edwinb / things.idr
Last active August 29, 2015 14:25
Concurrent processes in Idris
import Process
import Data.Vect
data Counter : Type -> Type where
GetIdle : Counter Int
Append : Vect n a -> Vect m a -> Counter $ Vect (n + m) a
data Maths : Type -> Type where
Factorial : Nat -> Maths Nat
@edwinb
edwinb / pairfail.idr
Created July 15, 2015 17:43
Overenthusiastic erasure
-- This segfaults, due to an erased name being used in the case
-- block generated for the 'j'' binding
foo : Nat -> ((Int, String) -> Nat -> IO a) -> IO a
foo Z k = k (0, "End") Z
foo (S j) k = foo j (\(i', s'), j' => k (i'+1, s') j')
-- This doesn't segfault, since Idris treats the \j' as an ordinary binder
-- rather than a pattern matching one.
foo' : Nat -> ((Int, String) -> Nat -> IO a) -> IO a
foo' Z k = k (0, "End") Z
@edwinb
edwinb / Process.idr
Created July 12, 2015 14:39
Mucking about with processes again
module Process
import System.Concurrency.Raw
import Data.List
import System
-- Process IDs are parameterised by their interface. A request of type
-- 'iface t' has a response of type 't'
abstract
data ProcID : (iface : Type -> Type) -> Type where
@edwinb
edwinb / ragged.idr
Created July 8, 2015 14:42
Ragged arrays
import Data.Vect
data Ragged : List Nat -> Type -> Type where
Nil : Ragged [] a
(::) : Vect n a -> Ragged ns a -> Ragged (n :: ns) a
test_ragged : Ragged [1,3,2] String
test_ragged = [["Foo"],
["Bar", "Baz", "Quux"],
["Thurlingdrome", "Bananas"]]
@edwinb
edwinb / tlsort.idr
Last active August 29, 2015 14:23
Type level quicksort
qsort : Ord a => List a -> List a
qsort [] = []
qsort (x :: xs) = let (l, r) = partition (< x) xs in
assert_total (qsort l ++ x :: qsort r) -- assert totality otherwise it won't reduce in the type
data Singleton : a -> Type where
MkSingleton : Singleton x
t_qsort : Ord a => (xs : List a) -> Singleton (qsort xs)
t_qsort xs = MkSingleton
@edwinb
edwinb / Process.idr
Last active August 29, 2015 14:23
More concurrency in Idris
module Main
import System.Concurrency.Raw
%access public
-- Process IDs are parameterised by the type of request they are willing to
-- take (req, which is implicit), and a function which calculates the type of
-- response they'll send
abstract
@edwinb
edwinb / answer.md
Last active February 9, 2023 12:14 — forked from non/answer.md

What is the appeal of dynamically-typed languages?

Kris Nuttycombe asks:

I genuinely wish I understood the appeal of unityped languages better. Can someone who really knows both well-typed and unityped explain?

I think the terms well-typed and unityped are a bit of question-begging here (you might as well say good-typed versus bad-typed), so instead I will say statically-typed and dynamically-typed.

I'm going to approach this article using Scala to stand-in for static typing and Python for dynamic typing. I feel like I am credibly proficient both languages: I don't currently write a lot of Python, but I still have affection for the language, and have probably written hundreds of thousands of lines of Python code over the years.

@edwinb
edwinb / scoped.idr
Last active August 29, 2015 14:13
Scoped implicits and type classes
AnyST : Type -> Type -> Type
AnyST s a = {m : _} -> Monad m => StateT s m a
foo : AnyST Integer ()
foo = do x <- get
put (x + 1)
wibble : StateT Integer Maybe ()
wibble = foo
@edwinb
edwinb / door.idr
Created October 31, 2014 15:11
State machines in types
-- Version 1, no possible failure
openDoor : { [DOOR Closed] ==> [DOOR Open] } Eff ()
openDoor = call OpenDoor
closeDoor : { [DOOR Open] ==> [DOOR Closed] } Eff ()
closeDoor = call CloseDoor
knock : { [DOOR Closed] } Eff ()
knock = call Knock