Skip to content

Generalize and expose the conversion machienery #91

@ShapeOfMatter

Description

@ShapeOfMatter

I've been playing around with functions to build Vec n as from infinite Streams and state-like functions (e.g.). We could certainly have a function like fromFunctor :: (Functor f1, Applicative f2) => ... -> f1 a -> f2 (Vec n a). This would be able to subsume* the existing implementations of fromListPrefix and fromList.

* fromListPrefix certainly; fromList may be a proud nail.

Here's what I've got so far:

newtype FromFunctor f1 f2 n a = FromFunctor { getFromFunctor :: (Functor f1, Functor f2) => f1 a -> f2 (Vec n a) }

fromFunctor :: forall f1 f2 n a.
               (SNatI n, Functor f1, Applicative f2) =>
               (f1 a -> f2 a) -> 
               (f1 a -> f1 a) ->
               f1 a -> f2 (Vec n a)
fromFunctor mkHead mkTail = getFromFunctor $ induction1 start step
  where start :: FromFunctor f1 f2 'Z a
        start = FromFunctor $ const $ pure VNil
        step :: forall m. FromFunctor f1 f2 m a -> FromFunctor f1 f2 ('S m) a
        step (FromFunctor f) = FromFunctor $ \f_1 -> (:::) <$> (mkHead f_1) <*> (f $ mkTail f_1)

-- These usage examples, while useful, would involve new dependencies: 

fromStream :: SNatI n => Stream a -> Vec n a
fromStream = runIdentity . (fromFunctor (Identity . Data.Stream.head) Data.Stream.tail)

unfold :: forall s n a.
          SNatI n =>
          (s -> (a, s)) ->
          (s -> (Vec n a, s))
unfold = runState . (fromFunctor id id) . state

Would you like me to put together a pull request?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions