Code Monkey home page Code Monkey logo

Comments (12)

simonmichael avatar simonmichael commented on July 30, 2024
  • using listSelectedL seems difficult sometimes, again because of this Monoid issue. I thought this would work:
>>> :t accountsScreen ^. asState . asItems
accountsScreen ^. asState . asItems :: List AccountsScreenItem
>>> :t accountsScreen ^. asState . asItems . listSelectedL

<interactive>:1:19:
    No instance for (Monoid Int) arising from a use of ‘asState’
    In the first argument of ‘(.)’, namely ‘asState’
    In the second argument of ‘(^.)’, namely
      ‘asState . asItems . listSelectedL’
    In the expression:
      accountsScreen ^. asState . asItems . listSelectedL

from brick.

simonmichael avatar simonmichael commented on July 30, 2024

But this works:

>>> :t (accountsScreen ^. asState . asItems) ^. listSelectedL
(accountsScreen ^. asState . asItems) ^. listSelectedL :: Maybe Int

from brick.

simonmichael avatar simonmichael commented on July 30, 2024

It might be a misunderstanding of lens principles on my part. I can see how an accessor following one that returns multiple values could need to be a monoid.. but asItems gets a singular value - a List - so I'm confused.

from brick.

simonmichael avatar simonmichael commented on July 30, 2024

And here are the current type definitions: https://gist.github.com/simonmichael/f75813855f56c54b08e19f89155517da

from brick.

jtdaugherty avatar jtdaugherty commented on July 30, 2024

^. doesn't require a Monoid instance inherently; it depends on what is on the right hand side. The Haddock docs for ^. give an example. However! I learned something new, which is that the Monoid instance requirement is coming from the fact that you're generating a partial lens, asState, on the Screen type. microlens is being smart about lens generation: if you were to use asState on a Screen value that wasn't the right constructor, it would need to fail -- and it would use mempty of the appropriate Monoid to do so.

To do this it generates Lenses when they are total and Traversals when they are partial, and ^. requires a Monoid instance when used with a Traversal.The following code sample reproduced this for me (notice the use of ^? with the traversal instead of ^.):

data Testing =
    First { _thing :: Int
          , _other :: Int
          }
    | Second { _other :: Int
             }
makeLenses ''Testing

and the types of the lenses generated:

*Main Brick.Widgets.List Lens.Micro> :i other
other :: Lens' Testing Int
*Main Brick.Widgets.List Lens.Micro> :i thing
thing :: Traversal' Testing Int

and so:

*Main Brick.Widgets.List Lens.Micro> (Main.First 1 2) ^? thing
Just 1
*Main Brick.Widgets.List Lens.Micro> (Main.Second 3) ^? thing
Nothing
*Main Brick.Widgets.List Lens.Micro> (Main.Second 3) ^. other
3

Regarding the missing Monoid instance: List doesn't provide a Monoid instance because it's not really possible to say what an instance would look like in general if two lists have different item heights or names, and it isn't possible to say what mempty should look like. It also isn't possible to make such a Monoid obey the Monoid law mempty <> x = x since if the left hand side takes precedence the equation is false. You can define one for your app as long as it provides the semantics you expect, but I can't provide one in the library for this reason.

from brick.

simonmichael avatar simonmichael commented on July 30, 2024

That is very clarifying, thank you very much!

I would like to get rid of those partial record fields, but I haven't found a better solution yet.

I wonder how you are seeing those nice types in GHCI (Lens' & Traversal'). I get the more verbose:

*Hledger.UI.UITypes *Hledger.UI.Main Lens.Micro> :t asList
asList
  :: Applicative f =>
     (List AccountsScreenItem -> f (List AccountsScreenItem))
     -> Screen -> f Screen

with GHC 7.10.3 and the latest types.

from brick.

jtdaugherty avatar jtdaugherty commented on July 30, 2024

Now that we've explored what was going on here, is there anything remaining that you need me to address? Or can this be closed?

from brick.

simonmichael avatar simonmichael commented on July 30, 2024

Feel free to close it. I don't know if adding listSelectedElementL is appropriate.

from brick.

jtdaugherty avatar jtdaugherty commented on July 30, 2024

Right now listSelectedElement gives you back Maybe (Int, e). It sounds from your original request that you might want the lens-compatible version to give back something similar. Making this be a Setter would be tricky but it would be easy to make a Getter with this type:

listSelectedElementL :: SimpleGetter (List n e) (Maybe (Int, e))

so that you could then do

let maybeSel = someList^.listSelectedElementL
case maybeSel of
  Nothing -> ...
  Just _ -> ...

Is this what you have in mind?

from brick.

jtdaugherty avatar jtdaugherty commented on July 30, 2024

@simonmichael - this ticket has been open for a while. Do you still have anything specific you'd like to see here? Or can I close it?

from brick.

simonmichael avatar simonmichael commented on July 30, 2024

Close away, thank you @jtdaugherty .

from brick.

jtdaugherty avatar jtdaugherty commented on July 30, 2024

Thanks!

from brick.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.