Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tail in the DList instance is not efficient #14

Closed
andreasabel opened this issue Aug 31, 2021 · 7 comments · Fixed by #15
Closed

tail in the DList instance is not efficient #14

andreasabel opened this issue Aug 31, 2021 · 7 comments · Fixed by #15
Assignees
Labels
performance Efficiency/performance issue. upstream Has to be solved upstream.
Milestone

Comments

@andreasabel
Copy link
Collaborator

tail :: DList a -> DList a is essentially DList.fromList . Data.List.tail . DList.toList in dlist-1.0, which is losing efficiency over (Data.List.tail .). The latter cannot be implemented outside of dlist though, due to data abstraction.

See 8c20780#r55694269 and spl/dlist#98.

@andreasabel andreasabel added performance Efficiency/performance issue. upstream Has to be solved upstream. labels Aug 31, 2021
@spl
Copy link

spl commented Aug 31, 2021

A couple of things:

  • As I mentioned on Restore tail :: DList a -> DList a? spl/dlist#98, I changed tail to the current one since the previous tail was inefficient, and I think the current one is slightly better than toList . tail. The listlike implementation of tail is the same as the previous dlist implementation.
  • You could use the UnsafeDList approach, that @andreasabel mentioned, in listlike. I don't like it myself, but the option is there and perfectly acceptable.

@andreasabel
Copy link
Collaborator Author

@spl wrote:

  • You could use the UnsafeDList approach, that @andreasabel mentioned, in listlike. I don't like it myself, but the option is there and perfectly acceptable.

I don't think this is an option here because the constructor for DList is not exported ("data abstraction").

@spl
Copy link

spl commented Aug 31, 2021

I don't think this is an option here because the constructor for DList is not exported ("data abstraction").

It's exported from Data.DList.Internal.

@andreasabel
Copy link
Collaborator Author

@spl: I tried import Data.DList.Internal (DList(..)) but this gives me

src/Data/ListLike/DList.hs:11:1: error:
    Could not load module ‘Data.DList.Internal’
    it is a hidden module in the package ‘dlist-1.0’

That's to be expected when looking at the docs at https://hackage.haskell.org/package/dlist-1.0:

Modules
Data
Data.DList
Data.DList.DNonEmpty
Data.DList.Unsafe

(That's also the convention: Internal modules are not exported.)

@spl
Copy link

spl commented Aug 31, 2021

@andreasabel Sorry, I misremembered. Use Data.DList.Unsafe. It's been over a year since I did it. And I surprised myself to find that I actually have a test for that.

@spl
Copy link

spl commented Aug 31, 2021

@andreasabel Also, there's documentation on this under the heading of Abstraction at the link you provided: https://hackage.haskell.org/package/dlist-1.0.

@andreasabel
Copy link
Collaborator Author

@andreasabel Sorry, I misremembered. Use Data.DList.Unsafe. It's been over a year since I did it. And I surprised myself to find that I actually have a test for that.

Thanks for the guidance. I'll use this backdoor, then.

@andreasabel Also, there's documentation on this under the heading of Abstraction at the link you provided: https://hackage.haskell.org/package/dlist-1.0.

Thanks, I see this. (Actually, I do not want to do anything unsafe, the (Data.List.tail .) function does not break the invariant mentioned there.)

There is still a problem with accessing the documentation of Data.List.Unsafe, see spl/dlist#100.

andreasabel added a commit that referenced this issue Sep 1, 2021
PR #5 offered a workaround for the regression in `dlist-1.0` which
changed the type of the `tail` function for difference lists (so it does
not have the type `DList a -> DList a` of a tail function anymore).

The problem with #5 is that it collapses the difference list to
compute its tail.

Here, we offer a solution that does not collapse the difference list,
by precomposing the `Data.List.tail` with the underlying function
`[a] -> [a]` of a difference list.   Data.List.Unsafe gives us access
to this function.

This problem would better be fixed upstream, see
spl/dlist#98
@ddssff ddssff closed this as completed in #15 Sep 1, 2021
ddssff added a commit that referenced this issue Sep 1, 2021
Fix #14: efficient tail instance for difference list
@andreasabel andreasabel self-assigned this Sep 2, 2021
@andreasabel andreasabel added this to the 4.7.5 milestone Sep 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Efficiency/performance issue. upstream Has to be solved upstream.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants