A2FP / a2fp

Ann Arbor Functional Programming User Group
11 stars 3 forks source link

Typeclasses to Unify Collection Types #33

Open BebeSparkelSparkel opened 5 years ago

BebeSparkelSparkel commented 5 years ago

I've been working with multiple collection types like List, Sequence, Dequeue, Vector, and NonEmpty. It has been a frustrating process to switch between the different collection types, so I have been building typeclasses to unify the functions that they share in common. This way I can write functions that specify constraints of the type instead of specifying the actual collection type.

I would like to present what I have implemented and receive feedback on how to improve my implementation.

30min

filippovitale commented 5 years ago

Which language are you using for the implementation?

mwotton commented 5 years ago

wouldn't mind seeing the talk, but this is also the sort of thing that the lens library can help with - for instance, you can use Cons and Snoc to add things at the beginning and end of list-like structures.

http://hackage.haskell.org/package/lens-4.17/docs/Control-Lens-Cons.html#v:Snoc

On Sun, Dec 30, 2018 at 5:21 PM William Rusnack notifications@github.com wrote:

I've been working with multiple collection types like List, Sequence, Dequeue, Vector, and NonEmpty. It has been a frustrating process to switch between the different collection types, so I have been building typeclasses to unify the functions that they share in common. This way I can write functions that specify constraints of the type instead of specifying the actual collection type.

I would like to present what I have implemented and receive feedback on how to improve my implementation.

30min

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/A2FP/a2fp/issues/33, or mute the thread https://github.com/notifications/unsubscribe-auth/AAELgjBL1VQS1GncJSeoj7IzYq6-NmKEks5u-WaVgaJpZM4ZlJK5 .

-- A UNIX signature isn't a return address, it's the ASCII equivalent of a black velvet clown painting. It's a rectangle of carets surrounding a quote from a literary giant of weeniedom like Heinlein or Dr. Who. -- Chris Maeda

BebeSparkelSparkel commented 5 years ago

@mwotton I was talking with @jjant about this and he was suggesting Lenses as well, and I am researching them this week. It seems that I have unknowingly been writing lenses for the different containers that I have been using.
The more I learn about lenses the less sense the existence the container specific functions make. They seem to be the legacy of when lenses didn't exist. Examples: : for [] and <| for Seq

Do you know if those functions will be dropped in the future for the lens functions?

Also, it seems like lenses are ripe to become a language extension for things like pattern matching but I have not found such extension in the GHC Language Features

Here are some of the typeclasses that I have been making

class Length t where
  length :: t a -> Int

  lengthEq :: t a -> Int -> Bool
  lengthEq xs l = (== l) $ length xs

  lengthGT :: t a -> Int -> Bool
  lengthGT xs l = (> l) $ length xs

  lengthGTEq :: t a -> Int -> Bool
  lengthGTEq xs l = lengthGT xs $ l - 1

class Init t where
  init :: t a -> Maybe (t a)

class Tail t where
  tail :: t a -> Maybe (t a)

  drop :: Int -> t a -> Maybe (t a)
  drop 0 xs = Just xs
  drop i (tail -> Just xs) = drop (i - 1) xs
  drop _ _ = Nothing

infixr 5 <|
class Cons t where
  (<|) :: a -> t a -> t a
  (|>) :: t a -> a -> t a

class Singleton t where
  singleton :: a -> t a

class Index t where
  (!!) :: Int -> t a -> Maybe a

class Reverse t where
  reverse :: t -> t

class DeleteAt t where
  deleteAt :: Int -> t a -> Maybe (t a)

class Sort t where
  sort :: Ord a => t a -> t a
  sort = sortOn id

  sortOn :: Ord b => (a -> b) -> t a -> t a

class SplitAt t where
  splitAt :: Int -> t a -> Maybe (t a, t a)

class Zip t where
  zip :: t a -> t b -> t (a, b)
  zip = zipWith (,)

  zipWith :: (a -> b -> c) -> t a -> t b -> t c

  zip3 :: t a -> t b -> t c -> t (a, b, c)
  zip3 = zipWith3 (,,)

  zipWith3 :: (a -> b -> c -> d) -> t a -> t b -> t c -> t d
  zipWith3 f xs ys = zipWith ($) (zipWith f xs ys)

  zip4 :: t a -> t b -> t c -> t d -> t (a, b, c, d)
  zip4 = zipWith4 (,,,)

  zipWith4 :: (a -> b -> c -> d -> e) -> t a -> t b -> t c -> t d -> t e
  zipWith4 f xs ys zs = zipWith ($) (zipWith3 f xs ys zs)

class UnZip t where
  unzip :: t (a, b) -> (t a, t b)
  unzipWith :: (a -> (b, c)) -> t a -> (t b, t c)

instance (Functor t) => UnZip t where
  unzip = fmap fst &&& fmap snd
  unzipWith f = unzip . fmap f

-- Potentially Empty --

class Head t where
  head :: t a -> Maybe a

class Last t where
  last :: t a -> Maybe a

class Filter t where
  filter :: (a -> Bool) -> t a -> t a

class Take t where
  take :: Int -> t a -> t a
  takeWhile :: (a -> Bool) -> t a -> t a

class Empty t where
  empty :: t a

class IsEmpty t where
  isEmpty :: t a -> Bool

class FromNativeList t where
  fromNativeList :: [a] -> t a

class Replicate t where
  replicate :: Int -> a -> t a

-- NonEmpty --

class HeadNE t where
  headNE :: t a -> a
-- instance HeadNE t => Head t where head = Just . headNE

class LastNE t where
  lastNE :: t a -> a
-- instance LastNE t => Last t where last = Just . lastNE

class FilterNE t where
  filterNE :: (a -> Bool) -> t a -> Maybe (t a)

class TakeNE t where
  takeNE :: Int -> t a -> t a
  takeWhileLNE :: (a -> Bool) -> t a -> Maybe (t a)
BebeSparkelSparkel commented 5 years ago

@filippovitale Probably going to switch this over to a lens talk for haskell. I probably won't be ready this month, but I'll probably know enough next month to give the talk.

mwotton commented 5 years ago

I wouldn't expect lenses to become part of haskell syntax proper - there's still a bit of ideological tug-of-war over it. definitely useful for this sort of thing though.

BebeSparkelSparkel commented 5 years ago

After looking through lenses a bit it seems like haskell's type system is lacking expressiveness to adequately show what's going on. Is that a thing or am I just not familiar enough with lens?