Why does ghci not use relative paths? - haskell

If I have a project structured like this:
project/
src/
Foo.hs
Bar.hs
With files Foo.hs:
module Foo where
foo :: String
foo = "foo"
and Bar.hs:
module Bar where
import Foo
bar :: String
bar = foo ++ "bar"
If my current directory is src, and I enter ghci and run :l Bar.hs, I get the expected output:
[1 of 2] Compiling Foo ( Foo.hs, interpreted )
[2 of 2] Compiling Bar ( Bar.hs, interpreted )
Ok, modules loaded: Bar, Foo.
But if I move up to the project directory (which is where I'd prefer to stay and run vim/ghci/whatever), and try :l src/Bar.hs, I get:
src/Bar.hs:3:8:
Could not find module ‘Foo’
Use -v to see a list of the files searched for.
Failed, modules loaded: none.
Why does ghc not search for Foo in the same directory as Bar? Can I make it do so? And can I propagate that change up to ghc-mod and then to ghcmod.vim? Because I get errors about can't find module when I'm running my syntax checker or ghc-mod type checker in vim.
I'm running ghc 7.10.1.

The flag you're looking for is -i<dir>:
% ghci --help
Usage:
ghci [command-line-options-and-input-files]
...
In addition, ghci accepts most of the command-line options that plain
GHC does. Some of the options that are commonly used are:
-i<dir> Search for imported modules in the directory <dir>.
For example
% ls src
Bar.hs Foo.hs
% ghci -isrc
GHCi, version 7.8.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
λ :l Foo
[1 of 1] Compiling Foo ( src/Foo.hs, interpreted )
Ok, modules loaded: Foo.
λ :l Bar
[1 of 2] Compiling Foo ( src/Foo.hs, interpreted )
[2 of 2] Compiling Bar ( src/Bar.hs, interpreted )
Ok, modules loaded: Foo, Bar.
You can also pass ghc-mod the -i<dir> flag from within ghcmod.vim
If you'd like to give GHC options, set g:ghcmod_ghc_options.
let g:ghcmod_ghc_options = ['-idir1', '-idir2']
Also, there's buffer-local version b:ghcmod_ghc_options.
autocmd BufRead,BufNewFile ~/.xmonad/* call s:add_xmonad_path()
function! s:add_xmonad_path()
if !exists('b:ghcmod_ghc_options')
let b:ghcmod_ghc_options = []
endif
call add(b:ghcmod_ghc_options, '-i' . expand('~/.xmonad/lib'))
endfunction

Related

How to override `doctest` to use my `ghc`?

I have problem using doctest with QuickCheck on NixOS
-- code.hs
--
-- $setup
-- >>> import Test.QuickCheck
--
-- |
-- This test will pass
-- >>> 1 + 1
-- 2
--
-- This test use QuickCheck
-- prob> \xs -> reverse xs = reverse . id $ xs
--
-- The last test will fail to ensure doctest was running
-- >>> 1 == 0
-- True
--
main :: IO ()
main = pure ()
The default haskellPackages.doctest doesn't include QuickCheck
$ nix-shell -p haskellPackages.doctest --run 'doctest code.hs'
code.hs:4: failure in expression `import Test.QuickCheck'
expected:
but got:
<no location info>: error:
Could not find module ‘Test.QuickCheck’
It is not a module in the current program, or in any known package.
Examples: 3 Tried: 1 Errors: 0 Failures: 1
so I try to make an overrride version as mydoctest
# ~/.config/nixpkgs/overlays/doctest.nix
self: super:
with super.haskellPackages;
let
myghc = ghcWithPackages (p: with p;
[
QuickCheck
]);
in
{
mydoctest = doctest.override {
ghc = myghc;
};
}
It still can't find QuickCheck
$ nix-shell -p mydoctest --run 'doctest code.hs'
code.hs:4: failure in expression `import Test.QuickCheck'
expected:
but got:
<no location info>: error:
Could not find module ‘Test.QuickCheck’
It is not a module in the current program, or in any known package.
Examples: 3 Tried: 1 Errors: 0 Failures: 1
but it work if I call it via ghc
$ nix-shell -p mydoctest --run 'ghc -e ":!doctest code.hs"'
code.hs:15: failure in expression `1 == 0'
expected: True
but got: False
Examples: 3 Tried: 3 Errors: 0 Failures: 1
myghc is there but didn't use by mydoctest
$ nix-shell -p mydoctest --run 'doctest --version'
doctest version 0.16.0
using version 8.4.3 of the GHC API
using /nix/store/g1dj8c6h6g8rbb8cv9bgmp1h2f3bxk1l-ghc-8.4.3-with-packages/bin/ghc
$ nix-shell -p mydoctest --run 'which ghc'
/nix/store/qj3vnm903p77nxiraxqxm9b8gbz5rpia-ghc-8.4.3-with-packages/bin/ghc
How can I make doctest to use my override ghc ?
Haskell derivations are not suitable as nix-shell environments by themselves.
The Nixpkgs manual recommends creating a derivation for the purpose of a nix-shell only, using a ghcWithPackages invocation as a dependency.
If the file you're trying to run is part of a haskell package, you can use cabal2nix to do most of the work for you.
I recommend the latter, because it does not pollute your user-wide state (whether profile or user-specific overlay), it is easier to share with others and provides structure that is sufficient to scale from toy example to a valuable package.
I had the same problem trying to get my nix/haskell dev environment set up and found a solution in this reddit post. To get doctest to use a specific version of ghc you can set the environment variable NIX_GHC:
$ doctest --version
doctest version 0.16.3
using version 8.10.3 of the GHC API
using /nix/store/9bm9bs9c4zpl17zdk1d0azid44x3h99b-ghc-8.10.3/bin/ghc-8.10.3
$ export NIX_GHC=/nix/store/zvx9dmfqaa8wibygkbibg4kl98pfj9qv-ghc-8.10.3-with-packages/bin/ghc
$ doctest --version
doctest version 0.16.3
using version 8.10.3 of the GHC API
using /nix/store/zvx9dmfqaa8wibygkbibg4kl98pfj9qv-ghc-8.10.3-with-packages/bin/ghc

Cabal test producing errors for Haskell

My Main.hs file takes in commandline arguments:
module Main (toLowerStr, Result(..), grade, main) where
...
grade :: [String] -> String -> String -> (Bool, Result, [Highlight])
grade dictWords correctAnswer studentAnswer =
...
...
main :: IO ()
main = do
args <- getArgs
dict <- readFile $ args !! 0
...
Which works fine, except when I try to test. My testing file is
module Testing where
import Main
import Test.Hspec
main :: IO ()
main = do
dict <- readFile "dict.txt"
let dictWords = map toLowerStr $ lines dict
hspec $ do
describe "Validate passing answers" $ do
it "Match should be verified exactly" $ do
grade dictWords "house" "house"
`shouldBe` (True, Perfect, [])
Yet when I run cabal test it still gives me
Preprocessing test suite 'tests' for grade-0.1.0.0...
[2 of 2] Compiling Testing ( src/HSpecTests.hs, dist/build/tests/tests-tmp/Testing.o )
Linking dist/build/tests/tests ...
Running 1 test suites...
Test suite tests: RUNNING...
tests: Prelude.(!!): index too large
Test suite tests: FAIL
I'm pretty sure it's failing because of the calls to args in Main.main, because the executable itself works fine, and I don't see !! being used anywhere else.
How do I get tests to run?
EDIT: Used pattern matching in Main.hs:
main :: IO ()
main = do
[filename, correctString, studentString] <- getArgs
...
and the error is now
[1 of 2] Compiling Main ( src/Main.hs, dist/build/tests/tests-tmp/Main.o )
Linking dist/build/tests/tests ...
Running 1 test suites...
Test suite tests: RUNNING...
tests: user error (Pattern match failure in do expression at src/Main.hs:141:9-48)
Test suite tests: FAIL
EDIT 2: My entire grade.cabal file
-- Initial grade.cabal generated by cabal init. For further documentation,
-- see http://haskell.org/cabal/users-guide/
name: grade
version: 0.1.0.0
-- synopsis:
-- description:
license-file: LICENSE
author: Amos Ng <amosng#cmu.edu>
maintainer: Amos Ng <amosng#cmu.edu>
-- copyright:
category: Language
build-type: Simple
cabal-version: >=1.8
executable grade
main-is: Main.hs
-- other-modules:
build-depends: base, split ==0.2.*
hs-source-dirs: src
test-suite tests
ghc-options: -Wall
type: exitcode-stdio-1.0
main-is: HSpecTests.hs
other-modules: Main
build-depends: base, split ==0.2.*, hspec ==1.11.*
hs-source-dirs: src
GHC will always use as the entry point the function named main out of the module named Main. Since HSpecTests.hs is the Testing module, not the Main module, its main is completely ignored, instead favoring the main from the Main module. You should break your logic out of the Main module, leaving the Main module as a command-line stub. Then you’ll want to exclude that from the test build, and change module Testing to module Main in HSpecTests.hs.

GHCi error - "Not in scope: `isUpper'"

I'm learning haskell and I'm trying to write some simple functions. Everything worked well until I've used function isUpper. I'm unable to compile the project because of this error:
[1 of 1] Compiling Main ( C:\Users\...\src\Main.hs, interpreted )
C:\Users\...\src\Main.hs:147:25:
Not in scope: `isUpper'
Failed, modules loaded: none.
Prelude>
My code:
module Main where
main::IO()
main = undefined
stringIsUpper [] = True
stringIsUpper (x:ys) = (isUpper x) && (stringIsUpper(ys))
The goal of this code should be just to check if the inserted string consists of the uppercase letters.
I'm using EclipseFP for development
Thank you for your help
You need to import Data.Char to get isUpper.

Haskell: Beginner syntax question

a very simple question from a Haskell learner. I am working through Yet Another Haskell Tutorial and I am stuck on a simple syntax practice. The code given below: When I copy and paste it (from pdf) and then adjust the indentation it works fine, but when I type it out into an editor (in my case Notepad++) then it throws the following error:
Guess.hs:8:9: parse error on input ´hSetBuffering´
I made sure that I did not mix tabs and whitespaces (4 whitespaces) and I did not find a typo in the book. I am sure it is a very simple mistake so thanks for any input.
Nebelhom
Here is the code:
module Main
where
import IO
import Random
main = do
hSetBuffering stdin LineBuffering
num <- randomRIO (1::Int, 100)
putStrLn "I'm thinking of a number between 1 and 100"
doGuessing num
doGuessing num = do
putStrLn "Enter your guess:"
guess <- getLine
let guessNum = read guess
if guessNum < num
then do putStrLn "Too low!"
doGuessing num
else if read guess > num
then do putStrLn "Too high!"
doGuessing num
else do putStrLn "You Win!"
There's no syntax error that I can see, or reproduce:
$ ghci A.hs
GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
[1 of 1] Compiling Main ( A.hs, interpreted )
Ok, modules loaded: Main.
which means it is probably tabs. Did you insert a tab somewhere? And then use 4 spaces for indenting? Tabs are in general a bad idea in Haskell, as they lead to unintentional, and unintelligible, syntax errors.

How to get only the object file without main function by ghc?

[Source Code]
data FooBar = Foo | Bar
[Command]
$ ghc -c foo_bar.hs
foo_bar.hs:1:0: The function 'main' is not defined in module 'Main'
[Configuration]
Glasgow Haskell Compiler, Version 6.12.3, for Haskell 98, stage 2 booted by GHC
version 6.10.4
You should define your type in a module, and then compile it:
module Test where
data FooBar = Foo | Bar
By invoking ghc -c foo_bar.hs, the object file foo_bar.o will be generated without having to define main.

Resources