agentm / project-m36

Project: M36 Relational Algebra Engine
The Unlicense
895 stars 48 forks source link

can't infer ConstructedAtomType properly #225

Open YuMingLiao opened 5 years ago

YuMingLiao commented 5 years ago

Hi, @agentm

I was creating a schema by trying project-m36-typed example with CrashSafePersistence db, and then tried to test an insert by tutd. But I can't find a way to input ConstructedAtomType in tutd. I can input Just "something" but not Nothing. It seems tutd can't infer Nothing's type.

TutorialD (master/main): :showexpr temp
┌───────────────────────────────────┬──────────────────────┬───────────────────────┐
│phoneNumberComment::Maybe (a::Text)│phoneNumberEmail::Text│phoneNumberNumber::Text│
├───────────────────────────────────┼──────────────────────┼───────────────────────┤
│Just "12345"                       │"12345"               │"12345"                │
└───────────────────────────────────┴──────────────────────┴───────────────────────┘
TutorialD (master/main): insert temp relation{tuple{ phoneNumberComment (Just "12346"), phoneNumberEmail "12346", phoneNumberNumber "12346"}}
TutorialD (master/main): :showexpr temp
┌───────────────────────────────────┬──────────────────────┬───────────────────────┐
│phoneNumberComment::Maybe (a::Text)│phoneNumberEmail::Text│phoneNumberNumber::Text│
├───────────────────────────────────┼──────────────────────┼───────────────────────┤
│Just "12345"                       │"12345"               │"12345"                │
│Just "12346"                       │"12346"               │"12346"                │
└───────────────────────────────────┴──────────────────────┴───────────────────────┘
TutorialD (master/main): insert temp relation{tuple{ phoneNumberComment (Nothing), phoneNumberEmail "12346", phoneNumberNumber "12346"}}
ERR: TypeConstructorTypeVarsMismatch (fromList ["a"]) (fromList [])

And in the meantime, I can't auto-derive some newtype Atomable from base Atoms.

newtype SafeId = SafeId B.ByteString 
  deriving (Eq, Ord, Show, Generic) 
  deriving newtype (NFData, Binary)

--    * Couldn't match representation of type `proxy ByteString'
--                               with that of `proxy SafeId'
--        arising from the coercion of the method `toAtomType'
--          from type `forall (proxy :: * -> *).
--                     proxy ByteString -> ProjectM36.Base.AtomType'
--            to type `forall (proxy :: * -> *).
--                     proxy SafeId -> ProjectM36.Base.AtomType'
--      NB: We cannot know what roles the parameters to `proxy' have;
--        we must assume that the role is nominal
--    * When deriving the instance for (Atomable SafeId)

It's due to some type role issue. And change proxy to Proxy may work (saw this advice somewhere). Is there any reason to have a toAtomType :: proxy a -> ... with a type variable instead of the Proxy type?

agentm commented 5 years ago

The type inference problem is covered by #46 where there is thankfully an easy workaround by adding the type to the relation. The backend doesn't yet connect the type of the target relation and the "floating" relation, so relation{x Nothing}, in general` is insufficiently typed.

Regarding the second issue, I think it should be resolved by switching from newtype to data. The backend definitely doesn't support newtype structures, so even if you could get past this error, something else would go wrong. I'll think about how to resolve that.