Last active
February 4, 2019 21:47
-
-
Save mpilquist/518c4a400003da8f57a4427e09cf019d to your computer and use it in GitHub Desktop.
Frank example ported to Unison
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Unison port of the list index function implemented via state ability (from the Frank Do Be Do Be Do paper) | |
-- We'll need a collection that supports abilities (Unison's built-in Sequence and Stream are pure) | |
type List a = nil | cons a (List a) | |
-- Mapping over a list, polymorphic in ability | |
lmap : (a -> b) -> List a -> List b | |
lmap f as = case as of | |
List.nil -> List.nil | |
List.cons h t -> List.cons (f h) (lmap f t) | |
-- Convert to a sequence to get better printing at console | |
toSeq : List a -> [a] | |
toSeq as = case as of | |
List.nil -> [] | |
List.cons h t -> cons h (toSeq t) | |
-- We'll also need the ability to destructure pairs | |
fst : (a, b) -> a | |
fst p = case p of (a, b) -> a | |
snd : (a, b) -> b | |
snd p = case p of (a, b) -> b | |
-- Now we're ready to create a State ability | |
effect State s where | |
get : {State s} s | |
put : s -> {State s} () | |
state : s -> Effect (State s) a -> (s, a) | |
state s eff = case eff of | |
{ State.get -> k } -> handle (state s) in (k s) | |
{ State.put sn -> k } -> handle (state sn) in k () | |
{ a } -> (s, a) | |
next : '({State Nat} Nat) | |
next = '(fst (State.get, State.put (State.get Nat.+ 1))) | |
index : List a -> List (Nat, a) | |
index as = | |
result = handle (state 0) in (lmap (a -> (!next, a)) as) | |
snd result | |
xs = (List.cons 10 (List.cons 20 (List.cons 30 List.nil))) | |
> toSeq xs | |
> toSeq (index xs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment