Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Importing files from different folders with Haskell source code

Tags:

haskell

cabal

Say I have some folders laid out like this:

\Code
    \Haskell
        \euler
            \P1.hs
            \P2.hs
            \P3.hs
        \fermat
            \GS
                \primes.hs

There are some functions that I've written in primes.hs that I would like to use in P3.hs. Is there a way to load the functions from primes.hs into P3.hs without just copying and pasting the code, similar to the way you can import modules that are in the same folder? Can this be done with Cabal (I'm fairly new to Haskell, I haven't had a chance to become familiar with Cabal yet)? I know there's some way to do it by loading primes.hs manually with ghci, but I'd like to just be able to run P3.hs and have it work.

like image 459
realityChemist Avatar asked Sep 17 '25 21:09

realityChemist


2 Answers

If you create a cabal project this is pretty straightforward. I would recommend a structure like

project-name/
    src/
        Euler/
            P1.hs
            P2.hs
            P3.hs
        Fermat/
            GS/
                Primes.hs

Then when you cd /path/to/project-name, run cabal init, fill in the information as it prompts you, and you're just about set. The last thing you'll need to do is set up the module names. A module's name should reflect its location in your src folder, and since all module names must start with upper case letters this means you need to make sure your folders are capitalized properly as well. Here you would have the modules Euler.P1, Euler.P2, Euler.P3, and Fermat.GS.Primes. Declare the module names as module Module.Name where in each file as appropriate, and then you can import each from each other as you please. Module imports are always fully qualified as well, so if you want to import src/Euler/P1.hs in src/Euler/P2.hs, you would need to do it as import Euler.P1

You'll probably run into a few bumps along the way, but using cabal to manage your project is very useful in the long run. Learn the basics and you'll be setting up projects with ease.

like image 126
bheklilr Avatar answered Sep 19 '25 18:09

bheklilr


Haskell expects to find the module Foo.Bar.Baz in the file Foo/Bar/Baz.hs. If you name your modules according to what folder they're in, and you load them with your current working directory at the root of the tree, everything should turn out fine. You don't actually need Cabal just to make that work. (Although as your programs get bigger, it of course becomes quite worth learning Cabal.)

A Haskell file with no module declaration defaults to being called Main. To give the correct module name, you need to do something like

module Foo.Bar.Baz where

at the top of each source file. So, for example, if you start the file Code/Haskell/Euler/P1 with the declaration

module Euler.P1 where

and start from a command prompt pointed at Code/Haskell, you should be good.

Note that Haskell module names must start uppercase. I believe (but I'm not 100% certain) that matching against filenames is case-insensitive here. (Because Windows treats filenames as case-insensitive.)

like image 32
MathematicalOrchid Avatar answered Sep 19 '25 18:09

MathematicalOrchid