Skip to content

Instantly share code, notes, and snippets.

@Herteby
Created August 23, 2019 15:15
Show Gist options
  • Save Herteby/e24cb0a1ea5755c39ac853b9cb5d9700 to your computer and use it in GitHub Desktop.
Save Herteby/e24cb0a1ea5755c39ac853b9cb5d9700 to your computer and use it in GitHub Desktop.
module TypedDict exposing (Interface, TypedDict(..), derive)
import Dict exposing (Dict)
type TypedDict comparable k a
= TypedDict (Dict comparable a)
type alias Interface comparable k a b =
{ --BUILD
empty : TypedDict comparable k a
, singleton : k -> a -> TypedDict comparable k a
, insert : k -> a -> TypedDict comparable k a -> TypedDict comparable k a
, update : k -> (Maybe a -> Maybe a) -> TypedDict comparable k a -> TypedDict comparable k a
, remove : k -> TypedDict comparable k a -> TypedDict comparable k a
--QUERY
, isEmpty : TypedDict comparable k a -> Bool
, member : k -> TypedDict comparable k a -> Bool
, get : k -> TypedDict comparable k a -> Maybe a
, size : TypedDict comparable k a -> Int
--LISTS
, keys : TypedDict comparable k a -> List k
, values : TypedDict comparable k a -> List a
, toList : TypedDict comparable k a -> List ( k, a )
, fromList : List ( k, a ) -> TypedDict comparable k a
--TRANSFORM
, map : (k -> a -> b) -> TypedDict comparable k a -> TypedDict comparable k b
, foldl : (k -> a -> b -> b) -> b -> TypedDict comparable k a -> b
, foldr : (k -> a -> b -> b) -> b -> TypedDict comparable k a -> b
, filter : (k -> a -> Bool) -> TypedDict comparable k a -> TypedDict comparable k a
, partition : (k -> a -> Bool) -> TypedDict comparable k a -> ( TypedDict comparable k a, TypedDict comparable k a )
-- COMBINE
, union : TypedDict comparable k a -> TypedDict comparable k a -> TypedDict comparable k a
, intersect : TypedDict comparable k a -> TypedDict comparable k a -> TypedDict comparable k a
, diff : TypedDict comparable k a -> TypedDict comparable k b -> TypedDict comparable k a
}
derive : (k -> comparable) -> (comparable -> Maybe k) -> Interface comparable k a b
derive toComp fromComp =
{ --BUILD
empty = TypedDict Dict.empty
, singleton = \k v -> TypedDict (Dict.singleton (toComp k) v)
, insert = \k v (TypedDict dict) -> TypedDict (Dict.insert (toComp k) v dict)
, update = \k fn (TypedDict dict) -> TypedDict (Dict.update (toComp k) fn dict)
, remove = \k (TypedDict dict) -> TypedDict (Dict.remove (toComp k) dict)
--QUERY
, isEmpty = \(TypedDict dict) -> Dict.isEmpty dict
, member = \k (TypedDict dict) -> Dict.member (toComp k) dict
, get = \k (TypedDict dict) -> Dict.get (toComp k) dict
, size = \(TypedDict dict) -> Dict.size dict
--LISTS
, keys = \(TypedDict dict) -> Dict.keys dict |> List.filterMap fromComp
, values = \(TypedDict dict) -> Dict.values dict
, toList =
\(TypedDict dict) ->
Dict.foldr
(\c v list ->
case fromComp c of
Just k ->
( k, v ) :: list
Nothing ->
list
)
[]
dict
, fromList = \list -> TypedDict (List.foldl (\( k, v ) dict -> Dict.insert (toComp k) v dict) Dict.empty list)
--TRANSFORM
, map =
\fn (TypedDict dict) ->
TypedDict
(Dict.foldl
(\c v acc ->
case fromComp c of
Just k ->
Dict.insert c (fn k v) acc
Nothing ->
acc
)
Dict.empty
dict
)
, foldl =
\fn init (TypedDict dict) ->
Dict.foldl
(\c v acc ->
case fromComp c of
Just k ->
fn k v acc
Nothing ->
acc
)
init
dict
, foldr =
\fn init (TypedDict dict) ->
Dict.foldr
(\c v acc ->
case fromComp c of
Just k ->
fn k v acc
Nothing ->
acc
)
init
dict
, filter =
\fn (TypedDict dict) ->
TypedDict
(Dict.filter
(\c v ->
case fromComp c of
Just k ->
fn k v
Nothing ->
False
)
dict
)
, partition =
\fn (TypedDict dict) ->
Dict.partition
(\c v ->
case fromComp c of
Just k ->
fn k v
Nothing ->
False
)
dict
|> Tuple.mapBoth TypedDict TypedDict
-- COMBINE
, union = \(TypedDict dictA) (TypedDict dictB) -> TypedDict (Dict.union dictA dictB)
, intersect = \(TypedDict dictA) (TypedDict dictB) -> TypedDict (Dict.intersect dictA dictB)
, diff = \(TypedDict dictA) (TypedDict dictB) -> TypedDict (Dict.diff dictA dictB)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment