WIP on explorer

This commit is contained in:
Paul Chiusano 2014-12-05 19:56:09 -05:00
parent 56ecd3dfbf
commit 424f60710d
4 changed files with 92 additions and 12 deletions

View File

@ -6,9 +6,17 @@ data Moore i o = Moore (i -> Bool) o (i -> Moore i o)
transform : Moore i o -> Signal i -> Signal o
transform m i =
let s i m = step m i
let s i m = if steady m i then m else step m i
in extract <~ foldp s m i
{-| Unlike `transform`, only emits events when the input transitions to a new state. -}
transitions : Moore i o -> Signal i -> Signal o
transitions m i =
let s i (m,_) = if steady m i then (m,False) else (step m i,True)
states = foldp s (m,True) i
changes = lift snd states
in keepWhen changes (extract m) ((extract << fst) <~ states)
extract : Moore i o -> o
extract (Moore _ o _) = o
@ -21,6 +29,17 @@ steady (Moore same _ _) = same
duplicate : Moore i o -> Moore i (Moore i o)
duplicate m = Moore (steady m) m (step m >> duplicate)
moore : o -> (i -> Moore i o) -> Moore i o
moore o k = Moore (always False) o k
{-| A machine which stays in the same state whenever the input matches the predicate. -}
skips : (i -> Bool) -> Moore i o -> Moore i o
skips f (Moore same o k) = Moore (\i -> f i || same i) o (k >> skip f)
{-| Like `skips`, but only skips up to the first transition to a new state. -}
skip : (i -> Bool) -> Moore i o -> Moore i o
skip f (Moore same o k) = Moore (\i -> f i || same i) o k
contramap : (i0 -> i) -> Moore i o -> Moore i0 o
contramap f (Moore same o k) = Moore (f >> same) o (f >> k >> contramap f)

View File

@ -1,14 +1,29 @@
module Elmz.Signal where
import Time
import Either
import Either (Either)
import Elmz.Maybe
import Maybe
import Time
{-| Accumulates into a list using `foldp` during regions where `cond`
is `True`, otherwise emits the empty list. -}
accumulateWhen : Signal Bool -> Signal a -> Signal [a]
accumulateWhen cond a = foldpWhen cond (::) [] a |> lift reverse
{-| Alternate sending `input` through `left` or `right` signal transforms,
merging their results. -}
alternate : (Signal (Maybe a) -> Signal c)
-> (Signal (Maybe b) -> Signal c)
-> Signal (Either a b)
-> Signal c
alternate left right input =
let l = Either.either Just (always Nothing)
r = Either.either (always Nothing) Just
ls = justs (l <~ input)
rs = justs (r <~ input)
in merge (left ls) (right rs)
{-| Delay the input `Signal` by one unit. -}
delay : a -> Signal a -> Signal a
delay h s =
@ -64,6 +79,10 @@ foldpWhen' cond f z a =
fromMaybe : Signal a -> Signal (Maybe a) -> Signal a
fromMaybe = lift2 Elmz.Maybe.fromMaybe
{-| Ignore any events of `Nothing`. -}
justs : Signal (Maybe a) -> Signal (Maybe a)
justs s = keepIf Maybe.isJust Nothing s
{-| Statefully transform the `a` signal, using `f`. -}
loop : (a -> s -> (b, s))
-> s
@ -111,3 +130,4 @@ unchanged a = lift not (changed a)
{-| Only emit when the input signal transitions from `False` to `True`. -}
ups : Signal Bool -> Signal Bool
ups s = keepIf identity False s

View File

@ -1,12 +1,17 @@
module Unison.Explorer where
import Elmz.Moore (Moore)
import Elmz.Moore as Moore
import Elmz.Moore as M
import Elmz.Layout as Layout
import Elmz.Layout (Layout,Region)
import Graphics.Element (Element)
import Graphics.Element as E
import Graphics.Input as Input
import Graphics.Input (Input)
import Graphics.Input.Field as Field
import Keyboard
import Unison.Term (Term)
import Unison.Styles as Styles
{-|
@ -29,23 +34,48 @@ While OPEN
todo : a
todo = todo
states : Moore (S k v, Mode (k,v)) (Mode (k,v))
states = todo
-- question - how does `sampleOn` work?
-- if I have sampleOn (events f s) s, this seems like
-- need to track whether explorer is open or closed in a simpler way
-- maybe have the explorer just output the mode, and we choose whether
-- to display it or not separately
explorer : Moore (S k v) (Mode (k,v))
explorer = states
|> Moore.map (\a -> (a,a))
|> Moore.loop
explorer : Moore (S k v) (Element, Maybe (k,v))
explorer =
let s0 = M.moore (E.empty, Nothing) closed
closed s = case s.focus of
Nothing -> s0
Just (k,r) -> opened k r s
opened k r s = todo
in s0
data Mode e = Close | Accept e | Open Element
autocomplete : S k v -> Element
autocomplete s =
let ok = case s.parse (s.input.string) of
Nothing -> False
Just v -> length (s.match s.input.string [v]) > 0
fld = Field.field (Styles.autocomplete ok)
s.searchbox.handle
(.string >> s.parse)
""
s.input
in todo
-- data Mode e = Close | Accept e | Open Element
data Direction = North | South | East | West
type S k v =
{ isKeyboardOpen : Bool
, goal : Element
, current : Element
, input : Field.Content
, searchbox : Input (Maybe v)
, parse : String -> Maybe v
, focus : Maybe (k, Region)
, overall : Region
, completions : [Layout v]
, highlight : Maybe Int -- index into `completions`
, match : String -> [v] -> [v]
, completions : [(Element,v)]
, mouse : (Int,Int)
, click : Maybe (Int,Int)
, movement : Maybe Direction }

View File

@ -2,6 +2,7 @@ module Unison.Styles where
import Text (Style)
import Text as T
import Graphics.Input.Field as Field
import Graphics.Element as E
import Graphics.Collage as C
import Elmz.Layout (Layout, Region)
@ -25,6 +26,15 @@ h1 =
, italic = False
, line = Nothing }
autocomplete : Bool -> Field.Style
autocomplete ok =
{ padding = { left = 10, right = 10, top = 5, bottom = 5 }
, outline = { color = if ok then turquoise else midnightBlue
, width = Field.uniformly 3
, radius = 0 }
, highlight = Field.noHighlight
, style = code }
code : Style
code =
{ typeface = [ "Inconsolata", "monospace", "latin" ]
@ -34,6 +44,7 @@ code =
, italic = False
, line = Nothing }
codeText : String -> Element
codeText s = leftAligned (T.style code (toText s))