Skip to content

Instantly share code, notes, and snippets.

@mpilquist
Last active February 4, 2019 21:47
Show Gist options
  • Save mpilquist/518c4a400003da8f57a4427e09cf019d to your computer and use it in GitHub Desktop.
Save mpilquist/518c4a400003da8f57a4427e09cf019d to your computer and use it in GitHub Desktop.
Frank example ported to Unison
-- 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