In Coq, `Export`, `Require`, and filtered_import do not work well - coq

In Coq, Export, Require, and filtered_import do not work well.
I made _CoqProject.
-R theories/ Library_Name
theories/A/B.v
theories/A.v
theories/C.v
I made theories/A/B.v.
Definition foo : _ := _.
I made theories/A.v.
Require Library_Name.A.B.
Export Library_Name.A.B (foo).
Definition baa : _ := _.
I made theories/C.v.
Require Library_Name.A.
Import Library_Name.A (baa).
Definition baz : _ := A.foo.
However, coqc said it could not find A.foo on theories/C.v.
What I want to hear is how to refer to A.B.foo as A.foo, which is better than redefining it in A.

Related

Purescript Import infix type constrctor

Here, \/ is from Data.Either.
This example is copied from the link above:
f :: (Int \/ String \/ Boolean) -> String
f = show \/ identity \/ if _ then "Yes" else "No"
What does the import statement look like?
Here you need to import both the type \/ and the value \/.
The syntax for importing type operators is type (\/). The prefix type is necessary for disambiguation - that is, to let the compiler know that you're importing the type, not the value that might have the same name.
And the syntax for importing the value is as usual.
So the whole import would look like this:
import Data.Either.Nested (type (\/), (\/))
In conclusion, I would recommend using your IDE integration (for example, here's a VSCode extension) to insert imports for you. That way you don't have to know the precise syntax.

Partial application is not allowed while using Function

I get the following error message:
"failure in proveterminate Error: Partial application of function convert_btree_to_tree in its body is not allowed while using Function"
from the following piece of Coq script, but I have no idea what is wrong. Can anyone give me some advice?
Function convert_btree_to_tree (t: btree (non_terminal' non_terminal terminal) terminal) {measure (fun t => bheight _ _ t)}:
tree (non_terminal' non_terminal terminal) terminal:=
let tl:= decompose t in
let ttl:= map convert_btree_to_tree tl in
let ttl':= convert_list_tree_to_tree_list ttl in
match broot _ _ t with
| inl n => node _ _ n ttl'
| inr t => node_t _ _ t
end.
Documentation on Function is very limited in the Reference Manual, does anybody know of a more complete and detailed reference, if possible with comments and examples?
I don't know much about Function but in your match, you return a node and a node_t. Since you didn't give the definitions, I don't know if these two constructors are from the same type, but I think you have a typo and the second case should return node t _ _ t.
EDIT after feedback from Marcus:
node_t is a constructor of tree which signature is terminal -> tree: given a term foo of type terminal, node_t foo is of type tree. node has the signature non_terminal -> tree_list -> tree.
Do you have any implicit parameters declared ? Otherwise, in your match cases, you apply too many arguments to node and node_t, which might be interpreted as partial application.

How to use liftDB function from the haskell package mongodb

I am new to Haskell (so please be patient with me) and I am trying to write a simple program that uses MongoDB.
I had no problem with the example written in the documentation of the package.
Then I found in the documentation the function liftDB and I could not figure out how it works.
Here it is what I tried:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Database.MongoDB
import Control.Monad
import Control.Monad.Reader
data MongoConfig = MongoConfig{ mContext :: MongoContext }
saveOnDB doc = do
_ <- liftDB $ insert "myDocs" doc
return ()
instance HasMongoContext MongoConfig where
mongoContext config = mContext config
main = do
saveOnDB []
putStrLn "hello everybody"
This gives me the error:
No instance for (MonadReader env0 IO)
arising from a use of `saveOnDB'
Possible fix: add an instance declaration for (MonadReader env0 IO)
In a stmt of a 'do' block: saveOnDB []
In the expression:
do { saveOnDB [];
putStrLn "hello everybody" }
In an equation for `main':
main
= do { saveOnDB [];
putStrLn "hello everybody" }
I was't expecting it to work since I never provided the MongoContext but here are the problems:
the data constructor for MongoContext is not exposed by the library, so I guess I am not supposed to create it directly.
it looks to me that it expects to find the MongoContext in a MonadReader instance.
This is the type signature of the function:
saveOnDB :: (HasMongoContext env, MonadIO m, MonadReader env m)
=> [Field] -> m ()
How can I make it work?
Based on your further comments below the question, you seem more interested in how to understand liftDB's type and how to use it if you had a MongoConfig on hand, than how to obtain said MongoConfig, so let's look at that.
The type of liftDB is
liftDB :: (HasMongoContext env, MonadIO m, MonadReader env m)
=> Action IO a -> m a
which means your saveOnDB function has the type
saveOnDB :: (HasMongoContext env, MonadIO m, MonadReader env m)
=> Document -> m ()
The intuition behind this type is that liftDB/saveOnDB can run in any monad m as long as it provides you a way to do IO in m (the MonadIO m constraint) and also to access a MongoContext at any point (it is basically required to be passed around behind the scenes; this is what MonadReader MongoContext m means).
To make things somewhat nicer to use in case you already have some other data that you pass around anyway, you don't have to pass around explicitly a MonadContext; anything from which we can extract a MonadContext will do (this is the meaning of the HasMongoContext env constraint)
The problem you are seeing, then, is that you are trying to set m ~ IO (and, I guess, in your real app, env ~ MongoConfig), but there is no MonadReader MongoConfig IO instance.
The solution by now should be obvious: the ReaderT monad transformer "tunnels" the MonadIO instance of the underlying monad (so if MonadIO m, then MonadIO (ReaderT env m), while providing access to some environment env. So if you choose env ~ MongoConfig and m ~ ReaderT MongoConfig IO, then you get something that will work exactly as intended.
In code terms, your main would look like this:
main = do
ctx <- error "This is the part we don't care in this answer"
let cfg = MongoConfig ctx
flip runReaderT cfg $ saveOnDB []
putStrLn "hello everybody"

Using monadic validation with Digestive Functors and Snap

I try quite a while now to wrap my head around how to use validation in a digestive functors form field, that requires access to another monad. To cut it short I have a digestive form like this
studentRegistrationForm :: Monad m => Form Text m StudentRegistrationData
studentRegistrationForm = StudentRegistrationData
<$> "school" .: choice schools Nothing
<*> "studentId" .: check studentIdErrMsg (not . T.null) (text Nothing)
<*> "firstName" .: check firstNameErrMsg (not . T.null) (text Nothing)
<*> "lastName" .: check lastNameErrMsg (not . T.null) (text Nothing)
<*> "email" .: check emailErrMsg (E.isValid . T.unpack) (text Nothing)
(studentId is basically the username)
and would like to use the function usernameExists of Snap.Snaplet.Auth to check if the entered username is unique.
Just for completeness, here is the corresponding data type:
data StudentRegistrationData = StudentRegistrationData
{ school :: School -- ^ school the student is enroled
, studentId :: Text -- ^ matriculation number of the student
, firstName :: Text -- ^ first name of the student
, lastName :: Text -- ^ last name of the student
, email :: Text -- ^ email for sending password
} deriving (Show)
I create my form in a handler like:
studentRegistrationHandler :: AppHandler ()
studentRegistrationHandler = do
(view, registrationData) <- runForm "form" SRF.studentRegistrationForm
maybe (showForm "registration" view) createUser registrationData
showForm :: String -> View Text -> AppHandler ()
showForm name view =
heistLocal (bindDigestiveSplices view) $ render template
where
template = BS.pack $ "student-" ++ name ++ "-form"
So the problem I have now is to understand how to access the state of the Auth snaplet inside the form. Is it passed already or do I have to passed it myself? Would the functions checkM respectively validateM in the Text.Digestive.Form help me there?
I have found several examples of how to use digestive functors and snap auth and session, like:
snap example
digestive functors tutorial
postgres example
Getting started with Snap-Auth
But none shows Snap.Snaplet.Auth and digestive functors working together directly, and I am still such a noob when it comes to monad transformers and lifting... maybe it is too easy for me to see. :(
I can upload a standalone example on github, which shows my problem if it helps to illustrate it. Any hints, pointers and suggestions are very welcome! :)
Hannes
add on: I created an example application demonstrating basic authentication functionality, you may have a look here: digestive-functors-snap-auth-example enjoy!
I haven't tried this out to see if everything type checks, but here's the general idea. You are correct that you want to use either checkM or validateM to do your monadic validation. The type signature for checkM is informative:
checkM :: Monad m => v -> (a -> m Bool) -> Form v m a -> Form v m a
This tells us that the validation function will need to have the type (a -> m Bool) and the m must be the same as the m in the form. This means that you need to change the type of your form to something like this:
studentRegistrationForm :: Form Text AppHandler StudentRegistrationData
Now let's write the validator. Since we plan on using the usernameExists function in our validator, we need to look at that type signature:
usernameExists :: Text -> Handler b (AuthManager b) Bool
This actually looks a lot like the (a -> m Bool) type signature that we need. In fact, it's an exact match because Handler b (AuthManager b) is a monad. But even though it matches the (a -> m Bool) pattern exactly doesn't mean we're done quite yet. When you run your form, you're in the AppHandler monad which is probably just a type alias for Handler App App where App is your application's top-level snaplet state type. So what we need to do is convert Handler b (AuthManager b) into Handler b b which will unify with Handler App App. The with function from the snaplet API is exactly what we need. This makes our validation function quite simple:
validUser :: Text -> Handler App App Bool
validUser = liftM not . with auth . usernameExists
With this, you can use checkM usernameErrMsg validUser just like you use check in the above code.

What is the shortest notation to define an operator as a method alias in Scala?

Given the generic register method below I would like to define the := operator as a symbolic alias.
def register[Prop <: Property[_]](prop: Prop): Prop
#inline
final def :=[Prop <: Property[_]] = register[Prop] _
Originally I wanted to write something like this:
val := = register _
But that gives me the function signature Nothing => Nothing. My next attempt was to parameterize it with the type Prop but that apparently works only if I make it a def, which can take type parameters and pass them onwards.
Ideally I would like to omit the #inline annotation but I am not sure what object code the Scala compiler makes out of it.
Most important my goal is it not to have the := method duplicate all parts of the register method's signature except for the name and then simply let the former delegate to the latter.
def :=[Prop <: Property[_]](prop: Prop) = register(prop)
should work.
I don't believe that there's any way to achieve what you're after (basically what alias gives you in Ruby) in Scala as it currently stands. The autoproxy plugin is an attempt to address this kind of problem, but it's not really ready for production use yet due to various issues with generating code in compiler plugins.
You can do this:
def := : Prop => Prop = register
So basically here you define a function of type (Prop => Prop) that just references another function.