Created
May 14, 2015 02:28
-
-
Save mbrcknl/c647ff697c1cd84bf832 to your computer and use it in GitHub Desktop.
Just some ideas from briefly mucking about with zippers with nkpart and newmana
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
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
import qualified Data.Map as M | |
import Control.Applicative as A | |
newtype JObject = JObject (M.Map String Json) | |
newtype JList = JList [Json] | |
data Json | |
= JLs JList | |
| JObj JObject | |
| JPrim String | |
| JNull | |
data ListContext = ListContext JList JList JContext | |
data ObjectContext = ObjectContext String JObject JContext | |
data JContext | |
= Top | |
| ListCtx JList JList JContext | |
| ObjectCtx String JObject JContext | |
data JZipper focus context = JZipper focus context | |
class Focus t where | |
focus :: JZipper Json context -> Maybe (JZipper t context) | |
blur :: JZipper t context -> JZipper Json context | |
instance Focus JObject where | |
focus (JZipper (JObj object) context) = Just (JZipper object context) | |
focus _ = Nothing | |
blur (JZipper object context) = JZipper (JObj object) context | |
class Up t c where | |
up :: JZipper (Maybe Json) c -> JZipper t JContext | |
instance Up JList ListContext where | |
up (JZipper focus (ListContext (JList left) (JList right) context)) | |
= JZipper (JList (reverse left ++ maybe id (:) focus right)) context | |
instance Up JObject ObjectContext where | |
up (JZipper focus (ObjectContext field (JObject object) context)) | |
= JZipper (JObject (M.update (const focus) field object)) context | |
class Down i t c where | |
down :: i -> JZipper t JContext -> Maybe (JZipper Json c) | |
instance Down String JObject ObjectContext where | |
down field (JZipper (JObject object) context) = refocus <$> M.lookup field object | |
where | |
refocus on = JZipper on (ObjectContext field (JObject (M.delete field object)) context) | |
-- TODO: get rid of the partial functions! | |
instance Down Int JList ListContext where | |
down index (JZipper (JList list) context) | |
| index < length list = Just $ JZipper (list !! index) (ListContext left right context) | |
| otherwise = Nothing | |
where | |
left = JList $ reverse $ take index list | |
right = JList $ drop (index+1) list | |
relabel :: (String -> String) -> JZipper focus ObjectContext -> JZipper focus ObjectContext | |
relabel f (JZipper focus (ObjectContext field others context)) | |
= JZipper focus (ObjectContext (f field) others context) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment