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

Generalize Undefined to work with non-errors too #748

Closed
martijnbastiaan opened this issue Aug 29, 2019 · 10 comments · Fixed by #803
Closed

Generalize Undefined to work with non-errors too #748

martijnbastiaan opened this issue Aug 29, 2019 · 10 comments · Fixed by #803
Assignees
Milestone

Comments

@martijnbastiaan
Copy link
Member

deepErrorX builds the structure/spine of a datatype and puts an error at its "core". This can be generalized such that it "lazyfies" a given type instead. Consider:

Clash.Prelude> x = errorX "foo" :: Vec 3 Int
Clash.Prelude> map (const 3) x
<*** Exception: X: foo

We could build lazify (for the lack of a better name) to achieve:

Clash.Prelude> x = lazify (errorX "foo") :: Vec 3 Int
Clash.Prelude> map (const 3) x
<3,3,3>

deepErrorX can now be defined as:

deepErrorX = lazify . errorX
@martijnbastiaan martijnbastiaan added this to the 1.1 milestone Aug 29, 2019
@martijnbastiaan martijnbastiaan self-assigned this Aug 29, 2019
@christiaanb
Copy link
Member

It's somewhat specific to products of a single type though... how do you generalize this to e.g. tuples?

@martijnbastiaan
Copy link
Member Author

I'm not sure I understand what you're saying. The implementation for a tuple would be something like:

instance (Undefined a, Undefined b) => Undefined (a, b) where
  -- lazify ~(a, b) = (lazify a, lazify b) ?
  lazify ab = 
    ( let (a, _) = ab in lazify a
    , let (_, b) = ab in lazify b
    )

@christiaanb
Copy link
Member

So what's the class supposed to look like?

@martijnbastiaan
Copy link
Member Author

class Undefined a where
  lazify :: a -> a

? Could you just explain what issues you're seeing?

@christiaanb
Copy link
Member

I don't see what the benefit is of having:

lazify (1,2,errorX "foo") :: (Int,Int,(Int, Int))

over

(1,2,deepErrorX "Foo" :: (Int,Int))

@martijnbastiaan
Copy link
Member Author

Ah right. It allows your to implement deepLazyV, if you will.

@martijnbastiaan
Copy link
Member Author

To be more specific, deepLazyV would be a type specialized version of lazify.

@martijnbastiaan
Copy link
Member Author

Does that make sense @christiaanb?

@christiaanb
Copy link
Member

Yeah, that makes sense

@jonfowler
Copy link
Contributor

@christiaanb a potential use case is when you have mux:

mux (errorX "undefined") (pure (repeat 0)) someVecSig

will produce errorX "undefined". With lazify you could write:

lazify $ mux ...

which will give you back the structure.

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

Successfully merging a pull request may close this issue.

3 participants