Last active
August 15, 2016 15:02
-
-
Save JoeyEremondi/b5b1be78d7c59aedf2347996d473702d to your computer and use it in GitHub Desktop.
This file contains hidden or 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
-- Given these simplified types: | |
data Model = Model { something :: SomeSubData } | |
data SomeSubData = SomeSubData { moreThing :: Integer } | |
-- And given this value | |
where | |
model = Model (SomeSubData 42) | |
-- You could do the way that Elm does now (although elm has the existing record inside the {} and haskell has it outside, so this is how haskell does it): | |
newModel = model { | |
something = (something model) { | |
moreThing = moreThing (something model) + 1 | |
} | |
} | |
-- The above set newModel as { something = { moreThing = 43 } } in Elmish parlance, and is very similar to how it is done in Elm itself, however Haskell has HKT's, which allow for a variety of other methods such as: | |
-- references+lenses (not possible to do anything even remotely like this in Elm right now due to not being able to operate over types, but it is the most succinct): | |
$(mkLabels [ 'Model, 'SomeSubData ]) -- Only need to do this once | |
newModel = modify (+1) (moreThing . something) model | |
-- SYB (A generic library that handles tasks like this with is, it comes bundled with Haskell | |
incMoreThing v s@(SomeSubData moreThing) = s { moreThing = moreThing + v } -- Per change you want to make anywhere in the record path | |
newModel = everywhere (mkT (incMoreThing 1)) | |
-- Semantic Editor Combinators (low-level version of SYB, no libraries needed, and you could make these 'now' in Elm, and I have to an extent, but it is very easy in haskell to define it from scratch, as doing here, still very wordy as it requires one function made per key): | |
type SemEdit a = a -> a | |
type Lifter p q = SemEdit p -> SemEdit q | |
onSomething :: Lifter SomeSubData Model | |
onSomething f (Model something) = Model (f something) | |
onMoreThing :: Lifter Integer SomeSubData | |
onMoreThing f (SomeSubData moreThing) = SomeSubData | |
newModel = (onSomething . onMoreThing) (+1) model |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment