Skip to content

deriving via can't coerce through functional dependencies

@RyanGlScott @Icelandjack at least in ghc 8.10.4, i've hit the following error

  error:
    • Couldn't match type ‘[BSC.ByteString]’ with ‘HoldingKey’
        arising from a functional dependency between:
          constraint ‘MonadOverlay
                        HoldingKey
                        BSC.ByteString
                        heapval
                        (OverlayM
                           (TP.TrieMap BSC.ByteString heapval)
                           (VariableScopeM (IndexVarMap heapval) m))’
            arising from the 'deriving' clause of a data type declaration
          instance ‘MonadOverlay [k] k v (OverlayM (TP.TrieMap k v) m1)’
            at <no location info>
    • When deriving the instance for (MonadOverlay
                                        HoldingKey
                                        BSC.ByteString
                                        heapval
                                        (ErasedInterpreterM heapval m))
    |
422 |   deriving (MonadOverlay HoldingKey BSC.ByteString heapval)
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

they definitely are coercible

newtype HoldingKey =  HoldingKey {getPath :: [BSC.ByteString]}

the deriving via i'm doing is (based on your unary constraint remark)

  deriving (MonadOverlay HoldingKey BSC.ByteString heapval)
   via OverlayM (TP.TrieMap BSC.ByteString heapval)  (VariableScopeM (IndexVarMap heapval) m )

where the underlying instance i'm coercing from is defined at the bottom of this snippet

class PartialTrieMap (mp :: * -> * -> *) k  {-  k v -> a-} where
  readMap :: mp k v   -> [k] -> Maybe v
  writeMap :: mp k v  -> [k] -> v -> mp k v
  {-# MINIMAL readMap,writeMap#-}
instance  (LBM.OrdMap DMS.Map k , Ord k) =>  PartialTrieMap (TP.TrieMap ) k     where
  readMap = \ mp v  -> TP.lookup v mp
  writeMap = \ mp k v -> TP.insert k v mp

class (Monad m)=> MonadOverlay  k segment  v m    |   m -> k v , k -> segment where
    overRead ::  k -> m (Maybe v)
    overWrite :: k -> v -> m ()
 ------ this instance below! 
instance (Monad m,Ord k,PartialTrieMap TP.TrieMap  k ) =>  MonadOverlay [k] k  v (OverlayM (TP.TrieMap k v) m)  where
  overRead = \ key ->  OverlayedM $ \ rd st ->
                     do
                       cacheread <- return $ readMap st key ;
                       case cacheread of
                          Just _v -> return (cacheread,st)
                          Nothing -> do  coldRead <- return $ readMap rd key ; return (coldRead,st)
  overWrite = \ key val -> OverlayedM $ \ _rd st -> return ((), writeMap st key val )

i can distill this down into a smaller example if needed

Edited by Carter Schonwald
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information