qfpl / applied-fp-course Goto Github PK
View Code? Open in Web Editor NEWApplied Functional Programming Course - Move from exercises to a working app!
Home Page: http://qfpl.io/projects/professional-fp-courses/
License: Other
Applied Functional Programming Course - Move from exercises to a working app!
Home Page: http://qfpl.io/projects/professional-fp-courses/
License: Other
With #23 comes a good time to include a discussion about the benefit of making a new module as needed. It's straightforward to do, and can be very useful for slicing up your functionality as required.
I have now completed the exercises in this repo (at least they compile...). However Since very early in the Levels, running cabal new-test test-suite:app-fp-tests
within nix-shell
(nixos) gives me
Test suite app-fp-tests: RUNNING...
and nothing more. Uncommenting each Level separately doesn't change that behaviour.
With cabal test test-suite:app-fp-tests
I get instead
cabal: no such test: test-suite:app-fp-tests
and finally, with cabal test app-fp-tests
and cabal new-test app-fp-tests
I get the same behaviour as with cabal new-test
.
Notice that this happens only when I complete each Level. I get proper error messages before completing a level.
A couple of points I found more challenging then I think they aught to be... This of course varies very much from person to person. And who they have around to answer questions.
A this was self study here are some points I think were harder to grasp.
It feels like the code is moving towards a pattern where the business logic is clean sperated from HTTP and DB layers. E.g. what is described well in: https://pragprog.com/book/swdddf/domain-modeling-made-functional
I think having some overview in the top level README of what the final process would with some tips:
Wai Request -(a)-> RqType -(b)-> Business Logic -> Event -> DB Dto -> DB -> Business Logic -> JSON Dto -> Response
Tips:
a. The goal of Core.hs mkRequest
b. The goal of Core.hs handleRequest
The rest of the chain is still not clear to me at the moment as I'm still progressing through that :)
After working through this and then looking at what is in the repository for Level04 I landed here:
app :: Application
app req respondWith = do
rqt <- mkRequest req
resp <- hResponseErr <$> hRqTypeErr rqt
respondWith resp
where
hRqTypeErr :: Either Error RqType -> IO (Either Error Response)
hRqTypeErr = either (pure . Left) handleRequest
hResponseErr :: Either Error Response -> Response
hResponseErr = either mkErrorResponse id
NOTE: I had changed the handleRequest to include the IO monad (so the above is slightly different than what you would do if you just did level 02 without doing that).
I think resp <- hResponseErr <$> hRqTypeErr rqt
is hard to come up with as a begineer from scratch. My first solution wasn't that nice...
However if the helpers hRqTypeErr
and hResponseErr
had been defined or at least stubbed as methods, I might have got there sooner. Maybe the struggle was worth it ;)
I think what took me time to understand is that the handling of Error happens at two different levels.
handleRequest
should be in the IO Monad in Level02Because you know this is going to be required at some point, I reworked the code in Level02 to include it there.
E.g. handleRequest :: RqType -> IO (Either Error Response)
Request
vs RqType
.It might have been more easily understood if RqType
had constructors AddCommand
, ListQuery
, ViewTopicQuery
. Or some other names to make the distinction clearer.
BUT OVERALL I HAVE FOUND THIS FUN AND INTERESTING!
Currently, the way level02's Types.hs
is laid out puts the newtype
definitions of Topic
and CommentText
a fair way down the screen, and probably "below the fold". I would hoist them above the definitions of Error
and ContentType
so they're visible when people write the different request constructors. Otherwise people might try to build them out of raw Text
s, and then go "oh, that's what this is for".
It's defaulted everywhere these days
Levels 05 and 07 mention monad transformers, but the exercises implement concrete custom monads.
Hi, Sean.
~/.stack/config.yaml
system-ghc: true
nix:
enable: true
packages: [ glpk pcre perl gcc ncurses zlib ]
When I run stack test
in level03, it compiles and runs the tests as expected. stack test --file-watch
, though, remains silent, apparently not compiling at start neither if I change anything in the test file.
Also,
$ ghcid -c "stack repl level03-tests"
Loading stack repl level03-tests ...
Warning: File listed in level03.cabal file does not exist: ChangeLog.md
The following target packages were not found: level03-tests
See https://docs.haskellstack.org/en/v1.4.0/build_command/#target-syntax for details.
Command "stack repl level03-tests" exited unexpectedly
ghcid -c "stack repl level03"
runs perfectly fine.
Guidance for where to go and what to do ...
The introductory course does not mention Bifunctor
or Foldable
/Traversable
. While covering all the standard typeclasses is beyond the scope of this course, the Bifunctor
instance for Either
and the Traversable
instance for []
are both extremely valuable. Maybe worth adding a note:
README.md
s (perhaps level04 when handling DB results?).The tests are all still broken out into their respective levels. Would it work better if there was a single set of tests which applied through out the entire course structure that could just be built upon?
Raised in discussion of #64
This would mean elimination of duplicate functionality across the test files. However it may complicate writing the tests as functionality for some levels will not exist to be tested. That appears to be trivially solvable via the power of comment syntax, but it's a consideration.
Following the readme instructions to try to confirm my environment is configured correctly:
$ cd <levelN>
$ cabal sandbox init
$ cabal configure
$ cabal install --only-dependencies
...
I got this output:
~/dev/git/applied-fp-course [master]✗ % cd level01
~/dev/git/applied-fp-course/level01 [master]✗ % cabal sandbox init
Writing a default package environment file to
/Users/dtchepak/dev/git/applied-fp-course/level01/cabal.sandbox.config
Creating a new sandbox at
/Users/dtchepak/dev/git/applied-fp-course/level01/.cabal-sandbox
~/dev/git/applied-fp-course/level01 [master]✗ % cabal configure
Resolving dependencies...
Warning: solver failed to find a solution:
Could not resolve dependencies:
trying: level01-0.1.0.0 (user goal)
unknown package: http-types (dependency of level01-0.1.0.0)
fail (backjumping, conflict set: http-types, level01)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: level01, http-types
Trying configure anyway.
Configuring level01-0.1.0.0...
cabal: Encountered missing dependencies:
http-types ==0.9.*, wai ==3.2.*, warp ==3.2.*
Running cabal install --only-dependencies
after this seemed to work fine.
The function is named FirstApp.DB.initDb
in level 4 and is FirstApp.DB.initDB
in level 5
In src/Level06/Conf/File.hs
:
Change
import Level06.AppM (AppM)
to
import Level06.AppM (AppM(runAppM))
and change
-- >>> readConfFile "badFileName.no"
-- Left (undefined "badFileName.no: openBinaryFile: does not exist (No such file or directory)")
-- >>> readConfFile "files/test.json"
-- Right "{\n \"foo\": 33\n}\n"
to
-- >>> runAppM $ readConfFile "badFileName.no"
-- *** Exception: badFileName.no: openBinaryFile: does not exist (No such file or directory)
-- >>> runAppM $ readConfFile "files/test.json"
-- Right "{\"foo\":33}\n"
This could just be a big time suck and not helpful for the course itself, but here goes anyway.
This is the tool I was talking about at the course the other day (kinda like dante, but for vscode instead of emacs): https://github.com/dramforever/vscode-ghc-simple
I was running:
I tried setting it to use cabal for the vscode project workspace, but it still wasn't initialising. The fp-course does with this vscode extension, but please note I was not using nix-shell for that one!
For ghcid with the applied course it was working with:
$> nix-shell
$ nix-shell> ghcid -c 'cabal new-repl'
so I suspect that if it was just run without nix, but with cabal directly it might work - I've not had a chance to test this theory however.
The tests are imported but they're initially commented out. There needs to be instructions for updating Test.hs
In level04, the comments suggest that our configuration is stored in a appconfig.json
file. There is no such file in level04, and the configuration is defined by Conf.hs. I've filed a PR #42 to amend this.
In level05: FirstApp.Conf.File.readObj
is confusingly named: it reads the contents of the config file and does not attempt to decode it to an object. Suggest renaming to FirstApp.Conf.File.readConfigFile
It might be worth having a few exercises where people write their own ReaderT
/ExceptT
, and set up the Functor
/Applicative
/Monad
/MonadTrans
instances before the level06/level07 exercises respectively.
You could then build everything with a fixed transformer stack, but then refactor out the explicit calls to lift
.
The main readme instructions for cabal install
/ cabal build
did not work for me to be able to run the tests. Ghcid prompted me to configure with tests enabled:
% .cabal-sandbox/bin/ghcid -c "cabal repl level03-tests"
Loading cabal repl level03-tests ...
cabal: Cannot process the test suite 'level03-tests' because test suites are
not enabled. Run configure with the flag --enable-tests
Command "cabal repl level03-tests" exited unexpectedly
% cabal configure --enable-tests
Resolving dependencies...
Warning: solver failed to find a solution:
Could not resolve dependencies:
rejecting: level03-0.1.0.0:!test (constraint from config file, command line
flag, or user target requires opposite flag selection)
trying: level03-0.1.0.0:*test
unknown package: hspec-wai (dependency of level03-0.1.0.0:*test)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: level03, level03-0.1.0.0:test,
hspec-wai
...
Instead I needed to do:
$ cabal sandbox init
$ cabal install --only-dependencies --enable-tests
$ cabal configure --enable-tests
Then I could run the ghcid command:
$ ghcid -c "cabal repl level03-tests"
# or for sandboxed ghcid:
$ .cabal-sandbox/bin/ghcid -c "cabal repl level03-tests"
Aside: Also might be worth mentioning that ghcid can check compilation and run the tests according to the FAQ (when compilation passes. The --warnings
flag tells ghcid to run the tests even if warnings are present.). I had varying levels of success with this:
.cabal-sandbox/bin/ghcid -c "cabal repl level03-tests" "--test=:main" --warnings
First time in runApp
https://github.com/qfpl/applied-fp-course/blob/master/level05/src/FirstApp/Main.hs#L49
Second time in prepareAppReqs
https://github.com/qfpl/applied-fp-course/blob/master/level05/src/FirstApp/Main.hs#L58
I think that runApp
is meant to call prepareAppReqs
instead and should not be concerned about how Conf
is instantiated.
Seems like target syntax may have changed?
We define configs and partial configs, but with HKD being used more often these days maybe we want a bonus level where you define
data Config f = Config
{ port :: f Port
, dbPath :: f DBFilePath
}
instance Semigroup (Config Last)
instance Monoid (Config Last)
?
Any plans to support GHC 8.2?
Seems to build by upping the bounds on base:
diff --git a/level01/level01.cabal b/level01/level01.cabal
index ebdd253..b5386ab 100644
--- a/level01/level01.cabal
+++ b/level01/level01.cabal
@@ -56,7 +56,7 @@ library
-ferror-spans
-- Other library packages from which modules are imported.
- build-depends: base >=4.9 && <4.10
+ build-depends: base >=4.9 && <4.11
, wai == 3.2.*
, warp == 3.2.*
, http-types == 0.9.*
@@ -78,7 +78,7 @@ executable level01-exe
-- other-extensions:
-- Other library packages from which modules are imported.
- build-depends: base >=4.9 && <4.10
+ build-depends: base >=4.9 && <4.11
, level01
-- Directories containing source files.
Happy to send a PR if this is something you'd be ok with.
♥ qfpl/applied-fp-course/level01 cabal install --only-dependencies 1m master :: 3h :: ⬢
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: level01-0.1.0.0 (user goal)
next goal: base (dependency of level01-0.1.0.0)
rejecting: base-4.11.0.0/installed-4.1... (conflict: level01 => base>=4.7 &&
<4.11)
rejecting: base-4.11.0.0, base-4.10.1.0, base-4.10.0.0, base-4.9.1.0,
base-4.9.0.0, base-4.8.2.0, base-4.8.1.0, base-4.8.0.0, base-4.7.0.2,
base-4.7.0.1, base-4.7.0.0, base-4.6.0.1, base-4.6.0.0, base-4.5.1.0,
base-4.5.0.0, base-4.4.1.0, base-4.4.0.0, base-4.3.1.0, base-4.3.0.0,
base-4.2.0.2, base-4.2.0.1, base-4.2.0.0, base-4.1.0.0, base-4.0.0.0,
base-3.0.3.2, base-3.0.3.1 (constraint from non-upgradeable package requires
installed instance)
fail (backjumping, conflict set: base, level01)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: base, level01
Note: when using a sandbox, all packages are required to have consistent
dependencies. Try reinstalling/unregistering the offending packages or
recreating the sandbox.
this is cause by the upper bound on base, maybe can be relaxed?
The bounds for hspec-wai
are currently == 0.8.*
but the LTS being used has spec-wai-0.9.0
. This should probably be relaxed to >= 0.8 && < 0.10
for all the test suites.
PS DB casing is still busted, noob.
Some students seemed to have trouble finding fromIntegral
. Might be worth mentioning in the run sheet or readme when the Word16
type is introduced during the configuration exercise.
FirstApp.Conf.File
has been implemented in level05
so level06
can have the implementation to avoid unnecessary copy/paste.
Codespaces are pretty much a dream for course work, this course should have that capability asap.
Note the code does not compile on a freash checkout of master.
This is the first error of a few. I think this is difficult for begineers because they are starting at Level01 and the whole project doesn't compile. So you have to sort that out first, the start with Level01.
$ cabal new-build
...
...
...
src/Level04/Types.hs:42:1-6: error: parse error on input ‘import’
|
42 | import Level04.Types.CommentText (CommentText, getCommentText,
| ^^^^^^
Warning: Failed to build documentation for applied-fp-course-0.1.0.0 (which is
required by exe:level07-exe from applied-fp-course-0.1.0.0, exe:level06-exe
from applied-fp-course-0.1.0.0 and others).
applied-fp-course (master)>
Cabal Version:
applied-fp-course (master)> cabal --version
cabal-install version 2.4.1.0
compiled using version 2.4.1.0 of the Cabal library
GHC Version:
OSX
applied-fp-course (master)> ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.4.3
I think nix expression should self-contains and not assume cabal-install
already exist on the system.
I try to add cabal-install
to default.nix
but somehow fail
$ git diff
diff --git a/default.nix b/default.nix
index 21e0aed..d51fa06 100644
--- a/default.nix
+++ b/default.nix
@@ -12,5 +12,6 @@ let
drv = haskellPackages.callPackage ./applied-fp-course.nix {};
+ drvWithTools = pkgs.haskell.lib.addBuildDepends drv [ pkgs.cabal-install ];
in
- drv
+ if pkgs.lib.inNixShell then drvWithTools.env else drv
$ nix-shell
error: attribute 'override' missing, at /nix/store/4vhnyxwg0bv15zvhqixgwhb1a1h5pa1w-source/pkgs/development/haskell-modules/lib.nix:37:28
Also introducing shell.nix
could be one way to solve the problem and open for adding additional tools (for example: linter, ide tools) to the shell.
Command: stack build --test
Error Message:
Configuring hspec-core-2.4.4...
Building hspec-core-2.4.4...
Preprocessing library hspec-core-2.4.4...
[ 1 of 22] Compiling Test.Hspec.Core.Timer ( src/Test/Hspec/Core/Timer.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Timer.o )
[ 2 of 22] Compiling Test.Hspec.Core.Compat ( src/Test/Hspec/Core/Compat.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Compat.o )
[ 3 of 22] Compiling Test.Hspec.Core.Formatters.Free ( src/Test/Hspec/Core/Formatters/Free.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Formatters/Free.o )
[ 4 of 22] Compiling Test.Hspec.Core.Util ( src/Test/Hspec/Core/Util.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Util.o )
[ 5 of 22] Compiling Test.Hspec.Core.QuickCheckUtil ( src/Test/Hspec/Core/QuickCheckUtil.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/QuickCheckUtil.o )
[ 6 of 22] Compiling Test.Hspec.Core.Example ( src/Test/Hspec/Core/Example.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Example.o )
[ 7 of 22] Compiling Test.Hspec.Core.Tree ( src/Test/Hspec/Core/Tree.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Tree.o )
[ 8 of 22] Compiling Test.Hspec.Core.Spec.Monad ( src/Test/Hspec/Core/Spec/Monad.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Spec/Monad.o )
[ 9 of 22] Compiling Test.Hspec.Core.Hooks ( src/Test/Hspec/Core/Hooks.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Hooks.o )
[10 of 22] Compiling Test.Hspec.Core.Spec ( src/Test/Hspec/Core/Spec.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Spec.o )
[11 of 22] Compiling Test.Hspec.Core.Formatters.Monad ( src/Test/Hspec/Core/Formatters/Monad.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Formatters/Monad.o )
[12 of 22] Compiling Test.Hspec.Core.Formatters.Internal ( src/Test/Hspec/Core/Formatters/Internal.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Formatters/Internal.o )
[13 of 22] Compiling Test.Hspec.Core.QuickCheck ( src/Test/Hspec/Core/QuickCheck.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/QuickCheck.o )
[14 of 22] Compiling Paths_hspec_core ( .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/autogen/Paths_hspec_core.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Paths_hspec_core.o )
[15 of 22] Compiling Data.Algorithm.Diff ( vendor/Data/Algorithm/Diff.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Data/Algorithm/Diff.o )
[16 of 22] Compiling Test.Hspec.Core.Formatters.Diff ( src/Test/Hspec/Core/Formatters/Diff.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Formatters/Diff.o )
[17 of 22] Compiling Test.Hspec.Core.Formatters ( src/Test/Hspec/Core/Formatters.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Formatters.o )
[18 of 22] Compiling Test.Hspec.Core.Options ( src/Test/Hspec/Core/Options.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/Options.o )
[19 of 22] Compiling Test.Hspec.Core.FailureReport ( src/Test/Hspec/Core/FailureReport.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Test/Hspec/Core/FailureReport.o )
ghc: panic! (the 'impossible' happened)
(GHC version 8.0.2 for x86_64-apple-darwin):
get IfaceTyLit 7
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
Students seem to be unclear about what alternatives they should define for ContentType
. Perhaps expand the comment to make it clear that we're only returning plain text or json?
Both stack build
and stack test
fail with undefined references to pthread symbols. I can fix stack build
by adding ghc-options: -threaded
option into executable section of a .cabal file. But similar trick doesn't work for a test-suite section. So I don't sure where exact issue is:
-threaded
to a test-suite section?I successfully built and tested all sections using nix-shell, and I used stack primarily for tooling. So this problem isn't a blocker since there are nix build files.
stack --version
Version 1.7.0, Git revision 066e7ce0c0f82dbc914a3e7be51fc356b42df737 x86_64 hpack-0.20.0
lsb_release -d
Description: Ubuntu 17.10
$ level04 [master] ⚡ stack test
Warning: File listed in level04.cabal file does not exist: ChangeLog.md
hspec-discover-2.4.4: configure
hspec-discover-2.4.4: build
Progress 1/4
-- While building custom Setup.hs for package hspec-discover-2.4.4 using:
/home/behemoth/.stack/setup-exe-cache/x86_64-linux/Cabal-simple_mPHDZzAJ_2.0.1.0_ghc-8.2.2 --builddir=.stack-work/dist/x86_64-linux/Cabal-2.0.1.0 build --ghc-options " -ddump-hi -ddump-to-file -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
Logs have been written to: /home/behemoth/Scratch/haskell/applied-fp-course_fix/level04/.stack-work/logs/hspec-discover-2.4.4.log
Configuring hspec-discover-2.4.4...
Preprocessing library for hspec-discover-2.4.4..
Building library for hspec-discover-2.4.4..
[1 of 3] Compiling Paths_hspec_discover ( .stack-work/dist/x86_64-linux/Cabal-2.0.1.0/build/autogen/Paths_hspec_discover.hs, .stack-work/dist/x86_64-linux/Cabal-2.0.1.0/build/Paths_hspec_discover.o )
[2 of 3] Compiling Test.Hspec.Discover.Config ( src/Test/Hspec/Discover/Config.hs, .stack-work/dist/x86_64-linux/Cabal-2.0.1.0/build/Test/Hspec/Discover/Config.o )
[3 of 3] Compiling Test.Hspec.Discover.Run ( src/Test/Hspec/Discover/Run.hs, .stack-work/dist/x86_64-linux/Cabal-2.0.1.0/build/Test/Hspec/Discover/Run.o )
Preprocessing executable 'hspec-discover' for hspec-discover-2.4.4..
Building executable 'hspec-discover' for hspec-discover-2.4.4..
[1 of 1] Compiling Main ( driver/hspec-discover.hs, .stack-work/dist/x86_64-linux/Cabal-2.0.1.0/build/hspec-discover/hspec-discover-tmp/Main.o )
Linking .stack-work/dist/x86_64-linux/Cabal-2.0.1.0/build/hspec-discover/hspec-discover ...
/usr/bin/ld: /home/behemoth/.stack/programs/x86_64-linux/ghc-8.2.2/lib/ghc-8.2.2/rts/libHSrts.a(OSThreads.o): undefined reference to symbol 'pthread_setname_np@@GLIBC_2.12'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
`gcc' failed in phase `Linker'. (Exit code: 1)
In level 07, Core.hs (in function app
)
Since mkErrorResponse
, now returns an AppM Response
.
When you run it, the return will be IO (Either Error a)
.
I'm a bit lost here, how do you handle the error case?
People seem to be confused that Text and ByteString have both strict and lazy variants. It might be worth adding a note to your run sheet or the readme explaining that both types exist.
#86 was jumping the gun: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html
https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Monoid.html#t:Last
This type will be marked deprecated in GHC 8.8, and removed in GHC 8.10. Users are advised to use the variant from Data.Semigroup and wrap it in Maybe.
I didn't notice earlier, but HSpec requires a Show
instance on the thing you check for a test result. This is silly and actually excludes some sensible tests or at least makes them awkward to write.
Remove HSpec and rewrite the tests using Tasty.
As logged here
When I followed the setup instructions in the ReadMe.md:
$ cd path/to/applied-fp-course
$ cabal sandbox init
$ cabal install --only-dependencies --enable-tests. < 3rd instruction generated errors
$ cabal build
$ $EDITOR README.md
Terminal session:
Alastairs-15-MBP:applied-fp-course aleith$ cabal install --only-dependencies --enable-tests
cabal: No sandbox exists at /Users/aleith/dev/applied-fp-course/.cabal-sandbox
Alastairs-15-MBP:applied-fp-course aleith$ cabal sandbox init
Writing a default package environment file to
/Users/aleith/dev/haskell/QFPL-course/applied-fp-course/cabal.sandbox.config
Using an existing sandbox located at
/Users/aleith/dev/haskell/QFPL-course/applied-fp-course/.cabal-sandbox
Alastairs-15-MBP:applied-fp-course aleith$ cabal install --only-dependencies --enable-tests
clang: error: unknown argument: '-no-pie'
`gcc' failed in phase `C Compiler'. (Exit code: 1)
Alastairs-15-MBP:applied-fp-course aleith$ cabal build
Resolving dependencies...
Warning: solver failed to find a solution:
Could not resolve dependencies:
[__0] trying: applied-fp-course-0.1.0.0 (user goal)
[__1] unknown package: warp (dependency of applied-fp-course)
[__1] fail (backjumping, conflict set: applied-fp-course, warp)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: applied-fp-course, warp
Trying configure anyway.
Configuring applied-fp-course-0.1.0.0...
cabal: Encountered missing dependencies:
aeson ==1.,
http-types >=0.9 && <0.13,
optparse-applicative >=0.13 && <0.15,
semigroups ==0.18.,
sqlite-simple ==0.4.,
sqlite-simple-errors ==0.6.,
wai ==3.2.,
warp ==3.2.
No experience with (the) cabal so not sure if it's up or down and why I need it. Will try to get started on the course regardless, but this is confusing for a new user (near-novice coder) looking at Haskell only b/c it's supposed to be the future of code.
The AppM
is parametrised over the error type, but could be useful when writing this function if it was. Either introduce and guide through ExceptT as a use case, or provide instructions on parameterising over the e
type for the AppM.
I found it helped a lot of people to have them work through the type of fmap . fmap
to apply a function inside two levels of Functor
. It may be worth mentioning this. It may also be worth not worrying about it and just closing this issue.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.