Closed gabebw closed 9 years ago
They do different things, and I find cabal repl
not useful in the context of Yesod app (or in general really).
Specifically, cabal repl
launches in the context of your executable, which typically has very little imported:
% cabal repl
λ> :browse
makeApplication :: AppConfig DefaultEnv Extra -> IO Application
makeFoundation :: AppConfig DefaultEnv Extra -> IO App
getApplicationDev :: IO (Int, Application)
Compared with opening a module (any module), which gives you immediate access to everything:
% cabal exec -- ghci Model.hs
λ> :browse
type Token = Text
type Validated a = Either [Text] a
type Validation a = a -> Validated a
type SubscriptionId = Key Subscription
data Subscription
= Subscription {subscriptionName :: !Text,
subscriptionUser :: !Key User,
subscriptionToken :: !Token,
subscriptionActive :: !Bool}
type CommentId = Key Comment
data Comment
= Comment {commentUser :: !Key User,
commentArticleURL :: !Text,
commentArticleTitle :: !Text,
commentArticleAuthor :: !Text,
commentThread :: !Text,
commentBody :: !Markdown,
commentCreated :: !UTCTime}
type UserId = Key User
data User
= User {userName :: !Text,
userEmail :: !Text,
userPlugin :: !Text,
userIdent :: !Text}
... and so on
The (only?) downside is that cabal exec -- ghci
bypasses your cabal file. That means you might get everything compiling this way then have to follow up separately (with cabal run
or cabal build
) to catch things like missing depends or exposed modules. I don't mind this myself, but cabal repl
would catch these issues as you work which some may prefer.
Specifically,
cabal repl
launches in the context of your executable
By default, it uses the first component listed in your .cabal
file, which is always the library for me. You can override it if you prefer a different component.
Compared with opening a module (any module), which gives you immediate access to everything
I like that it opens a specific module, but I do wish cabal repl
accepted a module to start with. You can use :m
or import
like normal ghci
, though:
% cabal repl
Preprocessing library carnival-0.0.0...
GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
...
[ 1 of 24] Compiling Network.Mail.SendGrid ( Network/Mail/SendGrid.hs, interpreted )
...
[24 of 24] Compiling Application ( Application.hs, interpreted )
Ok, modules loaded: Application, Import, Settings, Handler.Comments, Handler.Session, Handler.Embed, Handler.User, Handler.Feed, Handler.Unsubscribe, Foundation, Settings.Development, Settings.StaticFiles, Model, Model.Comment, Model.Subscription, Model.User, Model.UserComment, SendMail, Network.Mail.RecipientOverride, Network.Mail.SendGrid, Notification, Helper.Auth, Helper.Request, Helper.Validation.
*Application> import Model
*Application Model> :info User
data User
= User {userName :: !Text,
userEmail :: !Text,
userPlugin :: !Text,
userIdent :: !Text}
-- Defined at Model.hs:21:1
instance Eq (Key User) -- Defined at Model.hs:21:1
instance Eq User -- Defined at Model.hs:21:1
instance Ord (Key User) -- Defined at Model.hs:21:1
instance Read (Key User) -- Defined at Model.hs:21:1
instance Show (Key User) -- Defined at Model.hs:21:1
instance Show User -- Defined at Model.hs:21:1
instance PersistField User -- Defined at Model.hs:21:1
instance PersistField (Key User) -- Defined at Model.hs:21:1
instance PersistEntity User -- Defined at Model.hs:21:1
instance PathPiece (Key User) -- Defined at Model.hs:21:1
instance ToJSON (Entity User) -- Defined at Model/User.hs:15:10
instance ToJSON (Key User) -- Defined at Model.hs:21:1
instance FromJSON (Key User) -- Defined at Model.hs:21:1
data Unique User -- Defined at Model.hs:21:1
type PersistEntityBackend User -- Defined at Model.hs:21:1
newtype Key User -- Defined at Model.hs:21:1
data EntityField User -- Defined at Model.hs:21:1
By default, it uses the first component listed in your .cabal file, which is always the library for me. You can override it if you prefer a different component.
I tried to look this up / figure this out and couldn't. Do you get different :browse
output than I do, using the same (Carnival's) cabal file? How do I make it use the library target, which I assume has everything exported by all exposed modules? Or is it, but my assumption about the modules I'd get is wrong?
Do you get different
:browse
output than I do, using the same (Carnival's) cabal file?
No, if I follow your example, I get the same result. Because cabal repl
doesn't accept a module, you'll need to do :load Model
and then :browse
(or just :browse Model
).
My understanding of ghci is that:
Prelude
by default):module
or import
:load
In cabal repl
, it seems to use the first listed module of the first component. All other modules are loaded but not in scope unless you use :module
or import
.
Looks like they plan to add it:
Support for loading specific modules is planned but not implemented yet.
(from cabal help repl
)
In cabal repl, it seems to use the first listed module of the first component
That's seems pretty useless to me. I stand by my preference for ghci
.
@gabebw I think your change is good to merge.
Is
cabal exec ghci
preferable tocabal repl
?cc @thoughtbot/haskell