Disambiguating module and record access

96 views
Skip to first unread message

Brian Marick

unread,
Jan 12, 2017, 7:12:29 PM1/12/17
to elm-d...@googlegroups.com
Short: I am getting this error when `model_page` is a record inside module `Animals.Model`

Cannot find variable `Model.model_page.set`.

13|       model |> Model.model_page.set (Page.fromLocation location) |> noCmd
                         ^^^^^^^^^^^^^^
No module called `Model.model_page` has been imported. 

The relevant import statement is:

import Animals.Model as Model exposing (..)

How do I tell the compiler that `Model` contains a record with a `set` field, rather than that `Model.model_page` is a module with a top-level definition named `set`?
---------------
---------------

I’m using Monocle http://package.elm-lang.org/packages/arturopala/elm-monocle/latest for lenses with good success. It allows a reasonable approximation to the sort of deep accessors and “setters” that are easier in dynamically typed languages. For example, in Clojure, you can traverse a record with `(get-in record [:profile :name])

What a lens library allows is a record with `get` and `set` functions that work on a possibly-nested “part” of a larger whole. 

Because I’m obsessive about naming, I’ve being experimenting with how to make lenses available to client code. I previously slopped them all into a giant `Lenses.elm` namespace that was imported like this:

import Animals.Animal.Lenses exposing (..)

But I’d rather include the lens definitions alongside the `type alias` declarations that they apply to. That is:

type alias Model = 
  { page : Page.PageChoice
-- Boilerplate Lenses
      
model_page : UpdatingLens Model Page.PageChoice
model_page = lens .page (\ p w -> { w | page = p })

My goal is to stop using “import Animals.Animal.Lenses exposing (..)”. Instead, I’d have more specific imports and use qualified names like `Model.pageLens`. That is, instead of an implicit reference to the kind of the data the lens manipulates (“model_”), it’d be encoded in the module name as a convention I’d follow (“Model.*lens”). 

But the compiler error above is getting in my way.

For reference: 

Max Goldstein

unread,
Jan 12, 2017, 11:57:39 PM1/12/17
to Elm Discuss
Very tentatively, this might be a bug. I would think that because model_page is not capitalized, it should be interpreted as a value, not a module. That should resolve to a record that you can access a field on. I think your code can be unambiguously parsed.

(Where you might get into trouble is if module Foo defines a record type alias Bar, and there's also a module Foo.Bar. Though I still think that works because these are functions, not records, and you can't call a module name.)

Brian Marick

unread,
Jan 13, 2017, 3:12:00 PM1/13/17
to elm-d...@googlegroups.com
Thanks. I’ve filed an issue with a small reproducible example. https://github.com/elm-lang/elm-compiler/issues/1555

--
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 elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages