To do this without focus, you’d write something like:

updateCanvas : (Canvas -> Canvas) -> Model -> Model
updateCanvas fn  model =
    { model | canvas = fn model.canvas }

updateScale : (Int -> Int) -> Canvas -> Canvas -- probably put this in
Canvas module
updateScale fn canvas =
    { canvas | scale = fn canvas.scale }

inc x = x + 1

-- then in update...
    newModel = updateCanvas (updateScale inc) model

Another technique to avoid using focus is to have a flatter data structure
using extensible records (as described here
https://groups.google.com/d/msg/elm-discuss/g_hxu-tjzUQ/ah30ic4zHTQJ )

Finally, to answer your question, when using Focus, you have to define
canvas and scale yourself—they are not generated automatically. You would
write something like this (note the similarity to the updateCanvas and
updateScale functions in my first suggestion above):

canvas : Focus Model Canvas
canvas =
    Focus.create
        .canvas
        (\fn model -> { model | canvas = fn model.canvas })

scale : Focus Canvas Int
scale =
    Focus.create
        .scale
        (\fn canvas -> { canvas | scale = fn canvas.scale })

​

On Sun, Jun 19, 2016 at 3:58 AM, <[email protected]> wrote:

> I want to use the focus library to update a nested property per this
> example from the docs
> <http://package.elm-lang.org/packages/evancz/focus/2.0.1/Focus>:
>
> set (physics => velocity => x) 0 object
>
>
>
> My model is like this:
>
>   0     { canvas =
>   1         { width = 800
>   2         , height = 600
>   3         , scale = 1
>   4         , ratioToWorld = 10
>   5         }
>   6     , player = player
>   7     , enemy = enemy
>   8     }
>
>
> My update code is this:
>
>   0 update : Msg -> Model -> (Model, Cmd Msg)
>   1 update action model =
>   2   case action of
>   3     Step time ->
>   4       let
>   5         newScale = model.canvas.scale + 1
>   6         newModel = Focus.set (canvas => scale) newScale model
>   7       in
>   8         (newModel, Cmd.none)
>   9     NoOp ->
>  10       (model, Cmd.none)
>
> Initially I had a great deal of trouble with the compiler complaining
> about the "=>" operator but I got lucky and found a code example in github
> somewhere that showed me how to import it from the module with this:
>
>   0 import Focus
>   1 import Focus exposing ((=>))
>
>
> But I'm still getting syntax errors where it complains that it doesn't
> know what canvas, scale etc are:
> Detected errors in 1 module.
>
>
>
> -- NAMING ERROR ------------------------------------------------- ././
> Update.elm
>
> Cannot find variable `canvas`
>
> 17|         newModel = Focus.set (canvas => scale) newScale model
>                                   ^^^^^^
>
> -- NAMING ERROR ------------------------------------------------- ././
> Update.elm
>
> Cannot find variable `scale`
>
> 17|         newModel = Focus.set (canvas => scale) newScale model
>                                             ^^^^^
> Maybe you want one of the following?
>
>     List.scanl
>
>
> Any help with what I'm doing wrong would be appreciated.  I could work how
> to do it without using Focus but I plan/hope to use Focus a lot.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Elm Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to