G-d willing
Hello,
I have an error when I enable the ghc-option=-Wunused-top-binds
under build-options
of the daml.yaml
file.
I am getting a Defined but not used
error on data fields for a data-record. It is very strange, since the specific data record is being used. So why am I getting this error?
Here is the code I am having:
class ProvidesEnv a where
typeEnv : TypeEnv
typeEnv = foldl
(\typEnv (VarSpec ns n t _) -> TM.insert (qualName ns n) t typEnv)
baseTypeEnv
(envSpec @a)
mkEnv : a -> Env
mkEnv a = foldl
(\env (VarSpec ns n _ sel) -> TM.insert (qualName ns n) (sel a) env)
baseEnv
(envSpec @a)
envSpec : [VarSpec a]
instance (ProvidesEnv a, ProvidesEnv b) => ProvidesEnv (a, b) where
envSpec = (contraMap fst <$> envSpec @a) ++ (contraMap snd <$> envSpec @b)
where contraMap f (VarSpec ns n ft sel) = VarSpec ns n ft $ sel . f
qualName : Optional Text -> Text -> Text
qualName ns n = optional n (\ns -> ns <> "." <> n) ns
addConst : forall a b. (Namespaced a, ToVal b, HasExprType b) => Text -> b -> VarSpec a
addConst n v = addVar n $ const v
addVar : forall a b. (Namespaced a, ToVal b, HasExprType b) => Text -> (a -> b) -> VarSpec a
addVar n sel = VarSpec (namespace @a) n (exprType @b) (toVal . sel)
data VarSpec a = VarSpec with
ns : Optional Text
name : Text
fieldType : ExprType
selector : a -> Value
and I am getting this error on ns
, name
, fieldType
and selector
on the VarSpec
data record.
You’re not using the record fields anywhere. Your pattern matches always match on things positionally rather than via the field names.
You have a few different options:
- Change at least one of the pattern matches to match on field names.
- Add
VarSpec(..)
to your export list.
- Disable the warning at least for this file. You can add
{-# OPTIONS -Wno-unused-top-binds #-}
at the top of your file for that.
I am not sure I understand what you mean by that.
Also, if you can see, isn’t line 4 is using it?
(\typEnv (VarSpec ns n t _) -> TM.insert (qualName ns n) t typEnv)
Currently you have a positional match, i.e., your match does not care about the field names, it only cares about the order of the arguments.
(\typEnv (VarSpec ns n t _) -> TM.insert (qualName ns n) t typEnv)
If you change it to
(\typEnv (VarSpec with ns = ns, name = n, fieldType = t) -> TM.insert (qualName ns n) t typEnv)
the fields should be used (at least the first 3, for the selector you need to change the match in mkEnv
.
G-d willing
First thing first, I had in my export list VarSpec
however I did not have it the (..)
as you suggested. I tried that and it worked. So, first, can you please explain why adding this (..)
made a difference?
Second, I don’t understand the difference between the 2 lines you mentioned in your last reply. I thought that writing: VarSpec ns n t _
is the same as VarSpec with ns = ns, name = n, fieldType = t
is the same thing just 2 different ways to create a data record.
Exporting VarSpec
only exports the type name but not the constructor or the field selectors. VarSpec(..)
exports the type name, the constructor and the field selectors.
You are right that the two lines do the same thing. But one option uses the field names so to the compiler they are used. The other does not, so they are unused. I agree this is a bit quirky. It’s something inherited from Haskell rather than something we added deliberately.
1 Like