Does Literate Haskell support indexing function names, typeclasses and variable references? Is there a filter I can run on Literate Haskell source that will do this and give me either a nice PDF manual or a hyperlinked HTML document.
These are a really nice features of noweb and CWEB which I think it would spur widespread adoption of Literate Haskell.
As an example, look at the word count program written in CWEB. The code chunk on the first page in item #4 is footnoted with where that code is used. LHS doesn't support chunks but I'd like to know where the code is being used:
Comment describing func.
func = id
Used in: (X.Y.Z.f, A.B.C.g, Section 1.5)
func2 = indefined
Used in: (A.B.C.x, Section 2.1)
And additionally an index that aggregates all the function names and variables along where they're referenced in the document and by other functions etc.
There are some possibilities in Latex, the following uses the package listings, together with makeindex to create a list of all functions. Furthermore \label is used to create cross-references between different sections:
\documentclass[a4paper,11pt,reqno,twoside,pdflatex,makeidx]{amsart}
\usepackage[a4paper]{geometry}
\usepackage{listings}
\lstloadlanguages{Haskell}
\lstset{
flexiblecolumns=false,
basewidth={0.5em,0.45em},
basicstyle=\ttfamily,
language=haskell,
% numbers=left, % optional numbering of code lines
firstnumber=last,
numberstyle=\tiny,
stepnumber=2,
numbersep=5pt,
index={fac,fac2}
}
\lstnewenvironment{code}{}{}
\usepackage{hyperref}
\title{The factorial function}
\author{Federico Squartini}
\date{}
\makeindex
\begin{document}
\maketitle
\section{Factorial function}
\label{code:fac1}
The factorial function can be defined as:
\begin{code}
fac 0 = 1
fac n = n * fac (n-1)
\end{code}
\section{Factorial function in constant space}
The code for the factorial defined section~\ref{code:fac1} uses $o(n)$ stack
space. The following function uses constant space:
\begin{code}
fac2 n = go 1 1
where
go !acc i| i <= n = go (acc*i) (i+1)
| otherwise = acc
\end{code}
\printindex
\end{document}
Compile with:
pdflatex example.tex
makeindex example.idx
pdflatex example.tex
pdflatex example.tex
Resulting pdf is here. This is great for producing pdf files. For other kind of outputs (e.g. html) you should use latex together with pandoc.
Another option is to use pandoc's markdown syntax, mixed with ad hoc latex commands (\label and makeindex). This should simplify the task as well as producing less syntactic noise in the source files.
Related
I'm trying to use the wavefront-obj package to read an OBJ file. Here is an example of OBJ file.
After downloading this file, I do
import Data.WaveFrontObj
x <- loadWavefrontObj "pinecone.obj"
Then:
> :t x
x :: Either String WavefrontModel
import Data.Either.Extra
y = fromRight' x
Then:
> :t y
y :: WavefrontModel
> y
WavefrontModel []
Looks like the result is empty. What am I doing bad ?
Looks like your OBJ file has some directives that wavefront-obj doesn't recognize. You can see in the source that wavefront-obj only understands the #, v, vt, vn, and f directives. Your file kicks off with mtllib and o directives, and appears to have several others not in the supported list.
A priori, I would therefore expect a Left result instead of a Right as you're getting. But the wavefront-obj author fell into a common parser-combinator pitfall: their top-level parser does not end with eof. So it sees the first two comment lines, then none of its parsers match the next line but it doesn't mind not being at the end of the file, so it reports successfully parsing an empty list of directives.
Between this and a few other things I noticed while sourcediving (comments are almost certainly not treated correctly, failure to exploit the predictable structure of directives and therefore code duplication), I expect you're going to have to do quite a bit of work if you want this package to work reliably and correctly.
I am doing some haskell exercises to learn the language and I have a syntax error I was hoping someone could help me with:
-- Split a list l at element k into a tuple: The first part up to and including k, the second part after k
-- For example "splitAtIndex 3 [1,1,1,2,2,2]" returns ([1,1,1],[2,2,2])
splitAtIndex k l = ([l !! x | x <- firstHalfIndexes], [l !! x | x <- firstHalfIndexes])
where firstHalfIndexes = [0..k-1]
secondHalfIndexes = [k..(length l-1)]
The syntax error is "parse error on input ‘=’" and seems to be coming from my second where clause, but I can't work out why the first where clause is ok but not the second?
The Haskell Report specifies that tab characters flesh out text to the next multiple of eight. Your code appears to assume that it gets fleshed out to the next multiple of four. (My best guess. Might also be configured to be five or six, but those settings seem less popular than four.)
See my page on tabs for ideas on how to safely use tabs in Haskell code; or else do what most other folks do and configure your editor to expand tabs to spaces.
For an example of the style I use, your current code looks like this to the compiler (using > to mark tabs and _ for spaces):
splitAtIndex_..._=_...
> where_> firstHalfIndexes_=_...
> > > secondHalfIndexes_=_...
I would write it to look like this to the compiler:
splitAtIndex_..._=_...
> where_> firstHalfIndexes_=_...
> ______> secondHalfIndexes_=_...
This also looks correct with four-space tabstops (and indeed any size tabstop):
splitAtIndex_..._=_...
> where_> firstHalfIndexes_=_...
> ______> secondHalfIndexes_=_...
(Actually, I would probably just use one space after where rather than a space and a tab, but that's an aesthetics thing, not really a technical one.)
I just started Haskell and I'm struggling!!!
So I need to create a list om Haskell that has the formula
F(n) = (F(n-1)+F(n-2)) * F(n-3)/F(n-4)
and I have F(0) =1, F(1)=1,F(2)=1,F(3)=1
So I thought of initializing the first 4 elements of the list and then have a create a recursive function that runs for n>4 and appends the values to the list.
My code looks like this
let F=[1,1,1,1]
fib' n F
| n<4="less than 4"
|otherwise = (F(n-1)+F(n-2))*F(n-3)/F(n-4) : fib (n-1) F
My code looks conceptually right to me(not sure though), but I get an incorrect indentation error when i compile it. And am I allowed to initialize the elements of the list in the way that I have?
First off, variables in Haskell have to be lower case. Secondly, Haskell doesn't let you mix integers and fractions so freely as you may be used to from untyped or barely-typed languages. If you want to convert from an Int or an Integer to, say, a Double, you'll need to use fromIntegral. Thirdly, you can't stick a string in a context where you need a number. Fourthly, you may or may not have an indentation problem—be sure not to use tabs in your Haskell files, and to use the GHC option -fwarn-tabs to be sure.
Now we get to the heart of the matter: you're going about this all somewhat wrong. I'm going to give you a hint instead of a full answer:
thesequence = 1 : 1 : 1 : 1 : -- Something goes here that *uses* thesequence
Does anyone have a small working snippet of code to read strings from a file in Coq (the ynot library seems to do this, but I can't figure it out)?
Ynot can be found here: http://ynot.cs.harvard.edu/
The distribution contains an IO directory in the examples, which includes FS.v which defines things like:
Fixpoint ReadFile (fm : fd_model) (ms : list mode) (fd : File fm ms) (str : string) {struct str} : Trace :=
match str with
| EmptyString => Read fd None :: nil
| String a b => (ReadFile fd b) ++ (Read fd (Some a) :: nil)
end.
But I can't figure out how to invoke it.
I've tried things like:
Eval compute in ReadFile (File (FileModel "demo.txt") [R]).
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: The term "File (FileModel "demo.txt") [R]" has type "Set" while it is expected to have type "File ?16 ?17".
Similarly, the Quark project (http://goto.ucsd.edu/quark/) defines VCRIO.v with alternative mechanisms.
Any help would be much appreciated!
In general, you will not be able to perform file I/O directly inside Coq for the very simple reason that the underlying language Gallina is pure and total.
In particular, the function ReadFile you are looking at is not a function that reads a file, but a function that computes the trace generated by the action of reading a file.
The way we get around that in Quark (and its successor project Reflex http://goto.ucsd.edu/reflex ) is to axiomatize these effectful actions, see for instance https://github.com/UCSD-PL/kraken/blob/master/reflex/coq/ReflexIO.v from line 323 for the axiomatized type of our primitives.
So, on the Coq side, we reason using this monadic effectful type, and then once the code gets extracted, these axioms are realized with OCaml functions of the proper type, see here
https://github.com/UCSD-PL/kraken/blob/master/reflex/ml/primitives/ReflexImpl.ml line 111.
This obviously increases your trusted computing base, as you need to make sure your primitives do exactly what you axiomatized and no more.
To recap, there is no way we can execute effectful operations in Gallina itself, so we axiomatize these actions and can only really perform them with the extracted OCaml code.
I am unaware of any technique that would let you do these with rich types inside Gallina.
Modelling IO (by axiomatizing it) and setting it up for extraction (by realizing it) is similar to using Haskell's FFI. You won't be able to run the code in proofs or using the interpreter though. You will only be able to run it by extracting it and compiling it. But this is just a mere inconvenience. Imagine if you defined plus like this:
Axiom plus : nat -> nat -> nat.
Infix "+" := plus.
Axiom plus_0 : forall n1, n1 + 0 = n1.
Axiom plus_S : forall n1 n2, n1 + (S n2) = S (n1 + n2).
This wouldn't be executable, but you would still be able to prove everything you needed to prove about plus. The proof terms would be larger though. For example, eq_refl would no longer be a proof of 2 + 2 = 4. Also, Coq would no longer be doing any sanity checking.
For the "realizing" part, if you are extracting to Haskell, you do something like this:
Extract Constant plus => "(\ n1 n2 -> case n2 of
O -> n1
S n3 -> S (plus n1 n3))".
And then you extract it.
Extraction Language Haskell.
Recursive Extraction plus.
Now, try extracting without realizing.
In Haskell in 5 steps the factorial function is defined as follows:
let fac n = if n == 0 then 1 else n * fac (n-1)
But for hugs, it says that fac needs to be in fac.h. Can anyone explain why this is the case - missing the ability to define named functions seems like a massive limitation for an interpreter?
The basic answer as far as I can tell is that the Hugs interactive toplevel is essentially an expression parser, and function/data definitions are not expressions. Your example actually would work if you made it an expression and wrote let fac n = if n == 0 then 1 else n * fac (n-1) in fac 19. Adding support for this would be a pretty big effort, and apparently the Hugs implementors thought that it was good enough to require function/data definitions to be in files.
Hugs misses the ability to define any named functions (recursive or not). It also misses the ability to define data types.