Reflex Tutorial Upgrade (Part 4)
In my fourth attempt to update the Reflex FRP calculator tutorial to use the latest release of Obelisk, I was finally able to see the actual error that was causing the build failure. Perhaps now I can resolve it!
The build has been failing because mmark
0.0.7.1 requires megaparsec
>=7.0 && <8.0
, but that constraint cannot be
resolved. First, I would like to confirm the versions of these
packages.
I am using Obelisk revision
e3ec75f698.
The dep/reflex-platform
directory specifies Reflex Platform
revision 123a6f487c.
The nixpkgs
directory specifies obsidiansystems/nixpkgs
revision a78062dc78.
The hackage-packages.nix
files specifies that versions mmark
0.0.7.2 and megaparsec
8.0.0. These versions are consistent, but that is not the version of
mmark
in the error message, so some configuration must
specify a different version.
I found the configuration in the dep/mmark
directory of
the calculator-tutorial
repository. It specifies obsidiansystems/mmark
revision 350aee0f2d,
which is indeed mmark
0.0.7.1. When upgrading Obelisk, newer versions of Reflex Platform
and nixpkgs
are used, bringing along new versions of
dependencies, and this version of mmark
does not work with
the newer version of megaparsec
.
This special version of mmark
must have been used for a
reason. It is on a branch named th-lift+expose-internal
,
which may give a clue, but I do not see any further documentation.
Perhaps the newer version of mmark
in the new
nixpkgs
includes the changes that were required for the
tutorial? This is easy to test by commenting out the
hackGet
line for mmark
in the
default.nix
file.
diff --git a/default.nix b/default.nix
index d12d53b..2091741 100644--- a/default.nix
+++ b/default.nix
@@ -16,7 +16,7 @@ with pkgs.haskell.lib; {
ios.bundleName = "Obelisk Minimal Example";
__closureCompilerOptimizationLevel = null;
packages = {- mmark = hackGet ./dep/mmark;
+ # mmark = hackGet ./dep/mmark;
modern-uri = hackGet ./dep/modern-uri;
}; overrides = self: super: {
I tried building, and it failed with the following error.
frontend/src/Tutorial.lhs:1:1: error:
File name does not match module name:
Saw: ‘Main’
Expected: ‘Tutorial’
|
1 | # Tutorial
| ^
That .lhs
file is not in the Literate
Haskell format that is supported by GHC. It is a Markdown file with
the Haskell code in fenced code blocks, not prefixed with “bird tracks.”
This is done so that the Markdown can be displayed on GitHub. The markdown-unlit
program is used to convert from Markdown to valid Haskell source
code.
Note that this is the opposite of what LiterateX does. When using markdown-unlit, the source code is generated from a Markdown file. When using LiterateX, the Markdown documentation is generated from the source code.
The markdown-unlit
utility does not use mmark
as a dependency, so I do not
know what is going wrong. The use of markdown-unlit
is
configured in the frontend.cabal
file as follows.
ghc-options: -Wall -pgmL markdown-unlit
The markdown-unlit
utility is added to the frontend
build tools in the default.nix
file as follows.
frontend = overrideCabal super.frontend (drv: {
buildTools = (drv.buildTools or []) ++ [ self.buildHaskellPackages.markdown-unlit ];
});
The above error is displayed in an annoying full-screen interface
that hides any previous output. I was unable to determine a way to exit
the interface except for Ctrl+C
. After exiting, I was able
to scroll up and see that the output before the error has to do with
running GHCi! The command to load GHCi added markdown-unlit
as a visible package, but it does not include
-pgmL markdown-unlit
.
I found a file named ghcid-output.txt
that contains the
above error! Perhaps ghcid is failing to load
the source from the Markdown file. I do not want to give up, but this is
not a type of problem that I will run into when working on other
projects. I doubt that ghcid is used for
deployment, so I tried deploying locally to see if the project
builds.
$ nix-build -A exe --no-out-link
This attempt to build failed with the following error. The newer
version of mmark
does not include the changes that were
added to the fork, unfortunately. The tutorial relies on these special
changes.
Building library for frontend-0.1..
[1 of 4] Compiling Reflex.MMark.Render ( src/Reflex/MMark/Render.hs, dist/build/Reflex/MMark/Render.js_o )
src/Reflex/MMark/Render.hs:32:1: error:
Could not find module ‘Text.MMark.Internal.Type’
Use -v to see a list of the files searched for.
|
32 | import Text.MMark.Internal.Type hiding (Render (..))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/Reflex/MMark/Render.hs:33:1: error:
Could not find module ‘Text.MMark.Internal.Util’
Use -v to see a list of the files searched for.
|
33 | import Text.MMark.Internal.Util
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: builder for '/nix/store/818amz2yy1a9nn3iv9y7zqp4b9j3br6l-frontend-0.1.drv' failed with exit code 1;
last 10 log lines:
> 32 | import Text.MMark.Internal.Type hiding (Render (..))
> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> src/Reflex/MMark/Render.hs:33:1: error:
> Could not find module ‘Text.MMark.Internal.Util’
> Use -v to see a list of the files searched for.
> |
> 33 | import Text.MMark.Internal.Util
> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
For full logs, run 'nix log /nix/store/818amz2yy1a9nn3iv9y7zqp4b9j3br6l-frontend-0.1.drv'.
The changes in the mmark
fork are pretty small and
simple, so I could try applying the changes to a newer version of
mmark
that is compatible with the package versions
available in the latest version of Obelisk. I think I am going to stop
here, though, as I do not want to allocate any more time to this. I have
learned a lot, though, and I will likely write one more blog entry with
reflections.