Haskell: finding the source of an incomplete record build

I'm trying to debug a large, complex program in Haskell that I haven't completely written myself.

I'm trying to print your data structure to diagnose the error, but when I do, I get the following error: error: Prelude.undefined

. As you can see, this error is extremely uninformative.

I'm pretty sure this comes from an entry that I "partially" initialized, where I'm trying to access a field that hasn't been set.

The program (compiler) is distributed over two cabal projects, a library and an executable that uses this library. This makes debugging work using GHCI / cabal-repl hard: I can't get GHCi running on the executable because that's not the source of the error, but it is too difficult to manually recreate the input that the executable provides to the library.

I am wondering: what can I do to get more information about where the invalid record is being generated, which field is the source of the error, etc. Is there an RTS option or something I can use to give more information for the error output?

+3


source to share


2 answers


Compiling with -Wall (or -Werror) is a good first start to finding the source of an uninitialized field. However, this may not be the source of the error. The missing initialization of a record field has a special error message:

Prelude> data A = A { a :: Int } deriving Show
Prelude> A {}
A {a = *** Exception: <interactive>:11:1-4: Missing field in record construction a

      

If you add a strictness annotation to the record field, an error will be thrown at compile time:

Prelude> data A = A { a :: !Int } deriving Show
Prelude> let a = A { }

<interactive>:26:9:
    Constructor ‘A’ does not have the required strict field(s): a
    In the expression: A {}
    In an equation for ‘a’: a = A {}

      



Another option for finding the source of the error is to compile with profiling enabled and pass the -xc RTS flag.

From the GHC User Guide: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/runtime-control.html

-xc (Only available when the program is compiled for profiling.) When an exception is thrown in the program, this parameter causes the stack trace to be flushed to stderr.

This can be especially useful for debugging: if your program is complaining about an error [] and you have no clue what bit of code causes it to compile with -prof -fprof-auto and run with + RTS -xc -RTS will tell you exactly the call stack at the point the error was raised.

The result contains one report for each exception raised in (the program can raise and catch multiple exceptions during its execution), where each report looks like this:

*** Exception (message due to + RTS -xc), stack trace: GHC.List.CAF -> evaluated by: Main.polynomial.table_search,
called from Main.polynomial.theta_index, called from Main.polynomial, called from Main .zonal_pressure, called from Main.make_pressure.p, called from Main.make_pressure, called from Main.compute_initial_state.p, called from Main.compute_initial_state, called from Main.CAF ...

+6


source


If you use -Wall

cabal in the ghc options of your file, it will give a warning about incomplete entries.



module Foo where
data Bar = Bar { bar :: String, baz :: String }
f = Bar { baz = "foo" }

Foo.hs:5:5: Warning:
  Fields of ‘Bar’ not initialised: bar
  In the expression: Bar {baz = "foo"}
  In an equation for ‘f’: f = Bar {baz = "foo"}
Ok, modules loaded: Foo.

      

+7


source







All Articles