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

Define a Tupleable instance with a subrelation #351

Open
Valdsonjr opened this issue Sep 17, 2022 · 7 comments
Open

Define a Tupleable instance with a subrelation #351

Valdsonjr opened this issue Sep 17, 2022 · 7 comments

Comments

@Valdsonjr
Copy link

Right now, haskell datatypes with list attributes are derived as t :: List (a :: SomeTypeT) is there a way of forcing the deriving mechanism to use t :: relation {a::SomeTypeT} instead?

@YuMingLiao
Copy link
Contributor

YuMingLiao commented Sep 18, 2022

I couldn't find the code but I once wrote something like an instance Atomable a => Atomable Set a where toAtom = -- relation{element a})
And the Tupleable deriving mechanism works pretty well.

For what its worth, relation{element a} is a set and cannot keep duplicated elements while relation{index Integer, element a} can.

@Valdsonjr
Copy link
Author

Thanks, I will try that!

Do you guys think it's something useful to have? Should I make a pull request?

@agentm
Copy link
Owner

agentm commented Sep 23, 2022

A shortcut here could be to wrap the specific list item with newtype and add an Atomable instance for it that does what you want. In general, Tupleable and Atomable don't support subrelations by default because doing so would make the type variables more annoying.

Certainly, if you make some progress on this front, a PR would be much appreciated.

@agentm
Copy link
Owner

agentm commented Sep 28, 2022

@Valdsonjr , were you able to resolve this issue?

@Valdsonjr
Copy link
Author

@agentm I made it work with this ugly thing:

{-# LANGUAGE ScopedTypeVariables #-}

-- 'throws' something that is not a member of the Exception type class
throwIfLeft :: (Show a) => Either a b -> b
throwIfLeft = either (error . show) id

instance (Tupleable a, NFData a, Ord a, Serialise a, Show a) => Atomable (Set a) where
    toAtom :: Set a -> Atom
    toAtom set = RelationAtom (Relation attrs tuples)
        where
        tuples = RelationTupleSet $ map toTuple $ toList set
        attrs = toAttributes (Proxy :: Proxy a)

    fromAtom :: Atom -> Set a
    fromAtom (RelationAtom (Relation _ (RelationTupleSet tuples))) =
        fromList $ map (throwIfLeft . fromTuple) tuples
    fromAtom _ = error "wrong Atom constructor for (Set a)"

    toAtomType :: proxy (Set a) -> AtomType
    toAtomType _ = RelationAtomType (toAttributes (Proxy :: Proxy a))

I really wish I could remove some of those constraints, but at least it works for my toy programs

@agentm
Copy link
Owner

agentm commented Sep 29, 2022

That code is pretty straightforward- I'll wrap it into Project:M36, if you don't mind.

What bothers you about the constraints?

@Valdsonjr
Copy link
Author

Valdsonjr commented Sep 29, 2022

@agentm Sure! I can open the PR tomorrow night if you want. (and add the toAddTypeExpr)

What bothers you about the constraints?

I felt like there were too many constraints but on second thought I don't know of any other way

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

3 participants