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

mapProgramT #16

Closed
andrewthad opened this issue Mar 7, 2016 · 2 comments
Closed

mapProgramT #16

andrewthad opened this issue Mar 7, 2016 · 2 comments

Comments

@andrewthad
Copy link

In PR #15, I've added a function that makes it possible to map over the instruction type that ProgramT is parameterized over.

@andrewthad
Copy link
Author

From what I learned in #14, I thought that it would be possible to also write the functions

mapProgramT :: (forall a. instr1 a -> instr2 a) -> ProgramT instr1 m b -> ProgramT instr2 m b
hoistProgramT :: (forall b. m b -> n b) -> ProgramT instr m a -> ProgramT instr n b

without pattern matching on ProgramT. However, I still cannot find a way to write mapProgramT with pattern matching, so I think that this PR is still relevant.

@HeinrichApfelmus
Copy link
Owner

The same ideas from #14 can be used to write mapProgramT. Here is one way to do it:

mapProgramT :: Monad m => (forall a. instr1 a -> instr2 a)
    -> ProgramT instr1 m b -> ProgramT instr2 m b
mapProgramT f p = do
    v <- lift $ viewT p
    case v of
        Return a -> return a
        i :>>= k -> singleton (f i) >>= mapProgramT f . k

If I were to export the constructors, then this would kind of the defeat the purpose of the library. (Though I'm willing to compromise for the sake of efficiency). Relying on viewT only makes sure that the monad laws and the lifting laws are always satisfied. In contrast, having access to the internal constructors risks breaking these laws.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants