You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Effectful streams are a ubiquitous abstraction that will get used by lots of Unison programs. We want a nice, lightweight, efficient stream type that's well-integrated into Unison. Here's the Unison API:
dataStreamfainstanceMonadPlus (Streamf) -- Unison does not have typeclasses but you get the ideaeval::fa->Streamfauncons::Streamfa->Streamf (Maybe (a, Streamfa))
run::StreamRemote!a->Remote (Vectora)
fromVector::Vectora->Streamfa
It is expected that <|> (which is Stream append) and >>= (which is the same idea as the list monad) take constant time, rather than needing to traverse the left-hand expression.
I expect that Stream Remote a values will be very common - it's a stream that might pull data from multiple Unison nodes.
The implementation will be based on type-aligned sequences, following FS2:
dataStreamfa=Stream (forallb.Stackfab->Stackfab)
dataStackfabwhereEmpty::StackfaaConsBind:: (a->Streamfb) ->Stackfbc->StackfacConsEmit::a->Stackfab->StackfabConsEval::fa->Stackfab->StackfabConsAppend::Streamfa->Stackfab->Stackfab-- left as an exercise: implement `MonadPlus`, `eval`, `uncons`, and `run`
But we will have to defunctionalize this representation, so the functions are not Haskell functions but Unison functions, similar to what was done for Unison.Remote.
Subtasks:
As an exercise to check for understanding, implement pure Haskell version of Stream as given above. Post a compiling gist for reference.
Add defunctionalized version of Stream to Unison.Stream (open question - should we just add these as another constructor to Unison.Term, like we did for Remote? Or possibly bite the bullet and split out a separate Value type for representing runtime values, and add it there.)
Integrate into Unison builtins so these functions can be used from Unison
The text was updated successfully, but these errors were encountered:
@refried this was trickier than I thought. :) I got a compiling, working version after about 2 hours. Probably should have done that sooner rather than sending you on a wild goose chase. My bad. :( I hope this was still a good learning exercise.
I fiddled a bit with different representations and found it was pretty easy to express with the following:
{-# Language ScopedTypeVariables #-}
{-# Language BangPatterns #-}
{-# Language ExistentialQuantification #-}
{-# Language Rank2Types #-}
{-# Language GADTs #-}
moduleStreamwhereimportControl.ApplicativeimportControl.MonaddataStreamfa=foralla0.Stream (forallb.Stackfab->Stackfa0b)
dataStackfabwhereEmpty::StackfaaCons:: [Segmentfa] ->Stackfab->StackfabBind:: (a->Streamfb) ->Stackfbc->StackfacdataSegmentfawhereEmit::a->SegmentfaEval::fa->SegmentfaAppend::Streamfa->SegmentfadataViewLfabwhereUnbound:: [Segmentfa] ->ViewLfaaBound:: [Segmentfa] -> (a->Streamfb) ->Stackfbc->ViewLfac
From there the implementations of uncons and run became a lot more inevitable - you just unbind the stack, pattern match, and handle all the cases. It might be possible to implement in terms of the simpler representation I gave earlier.
With the earlier representation, implementing everything up through MonadPlus should still be trivial, it's just the two interpreters, uncons and run, that are much trickier.
If you'd still like to give this a try, start with the representation I just gave and go from there. Otherwise we can go over my 'answer' tomorrow.
Effectful streams are a ubiquitous abstraction that will get used by lots of Unison programs. We want a nice, lightweight, efficient stream type that's well-integrated into Unison. Here's the Unison API:
It is expected that
<|>
(which is Stream append) and>>=
(which is the same idea as the list monad) take constant time, rather than needing to traverse the left-hand expression.I expect that
Stream Remote a
values will be very common - it's a stream that might pull data from multiple Unison nodes.The implementation will be based on type-aligned sequences, following FS2:
But we will have to defunctionalize this representation, so the functions are not Haskell functions but Unison functions, similar to what was done for
Unison.Remote
.Subtasks:
Stream
as given above. Post a compiling gist for reference.Stream
toUnison.Stream
(open question - should we just add these as another constructor to Unison.Term, like we did forRemote
? Or possibly bite the bullet and split out a separateValue
type for representing runtime values, and add it there.)The text was updated successfully, but these errors were encountered: