snoyberg / classy-prelude

A typeclass-based Prelude.
108 stars 15 forks source link

head, tail, last, init #34

Closed nikita-volkov closed 10 years ago

nikita-volkov commented 11 years ago

I get that we don't export those functions because they are partial. I have two suggestions on that matter:

  1. As they do in Scala with a headOption method, we can export their "maybe"-suffixed versions (e.g., headMaybe), which will return Nothing in case of empty collection.
  2. Follow another Haskell's convention by prepending the partial versions with "unsafe" (as in unsafePerformIO) and exporting the safe versions in their place. I.e., export head :: [a] -> Maybe a and unsafeHead :: [a] -> a, but, of course, generalized with typeclasses.

First option doesn't break any existing conventional definitions. Second one follows the same "we know better" questionable approach as with the fold function.

What do you think?

snoyberg commented 11 years ago

unsafe generally implies things that can break the type system or cause a segfault, not something partial, so I wouldn't want to go in that direction. Maybe it's time to introduce the Failure typeclass and pull in safe-failure.

@jwiegley might be interested in that proposal.

nikita-volkov commented 11 years ago

@snoyberg What about Vector.unsafeHead?

snoyberg commented 11 years ago

That's a perfect example. Vector.head is memory safe and will throw an exception if the vector is empty. unsafeHead has the possibility of a segfault, but in exchange is a little bit faster.

jwiegley commented 11 years ago

@snoyberg Am certainly interested. What can I do to help here? I'm really the way that Failure manages error handling in my recent code.

snoyberg commented 11 years ago

I don't think any help is necessary, I thought I'd just let you know that there's a possibility of including more direct failure assistance in classy-prelude.

gregwebs commented 11 years ago

I am not against including the versions from the safe package, but personally I will start experimenting with NonNull from mono-traversable

jwiegley commented 11 years ago

I've found that one thing unsafe typically means is: it seems to work just fine at first, but comes back to bite you later. Nearly all of my segfaults in FFI code could be tracked down to an unsafeSomethingOrOther which worked just fine for a few months before memory shifted around and suddenly it wasn't safe to do anymore.

snoyberg commented 10 years ago

This should be addressed by the export of head and family from Data.MinLen in the next release.