program instalar como haskell cabal ghci runhaskell

instalar - haskell platform



¿Cómo hacer un proyecto Cabal de Haskell con biblioteca+ejecutables que aún se ejecutan con runhaskell/ghci? (2)

Puede usar cabal repl para iniciar ghci con la configuración del archivo cabal run y cabal run para ejecutar y ejecutar los archivos ejecutables. A diferencia de runhaskell y ghci , el uso de cabal repl y la cabal run también captan las dependencias de los runhaskell de cabal correctamente.

Si declara una biblioteca + secciones ejecutables en un archivo cabal mientras evita la compilación doble de la biblioteca colocando la biblioteca en un directorio hs-source-dirs , normalmente no puede ejecutar su proyecto con ghci y runhaskell , especialmente si los ejecutables tienen ayuda módulos ellos mismos.

¿Qué es un diseño de proyecto recomendado que

  • solo construye lo que se necesita una vez
  • permite usar runhaskell
  • tiene una estructura limpia sin hacks?

Supongamos que tiene una biblioteca mylib-commandline y mylib-commandline y mylib-server .

Utiliza hs-source-dirs para la biblioteca y cada ejecutable para que cada uno tenga su propia raíz de proyecto, evitando la compilación doble:

mylib/ # Project root mylib.cabal src/ # Root for the library tests/ mylib-commandline/ # Root for the command line utility + helper modules mylib-server/ # Root for the web service + helper modules

Diseño completo del directorio:

mylib/ # Project root mylib.cabal src/ # Root for the library Web/ Mylib.hs # Main library module Mylib/ ModuleA # Mylib.ModuleA ModuleB # Mylib.ModuleB tests/ ... mylib-commandline/ # Root for the command line utility Main.hs # "module Main where" stub with "main = Web.Mylib.Commandline.Main.main" Web/ Mylib/ Commandline/ Main.hs # CLI entry point Arguments.hs # Programm command line arguments parser mylib-server/ # Root for the web service Server.hs # "module Main where" stub with "main = Web.Mylib.Server.Main.main" Web/ Mylib/ Server/ Main.hs # Server entry point Arguments.hs # Server command line arguments parser

El archivo de punto de entrada similar a un stub mylib-commandline/Main.hs ve así:

module Main where import qualified Web.Mylib.Server.Main as MylibServer main :: IO () main = MylibServer.main

Los necesita porque un executable debe comenzar en un módulo simplemente llamado Main .

Tu mylib.cabal ve así:

library hs-source-dirs: src exposed-modules: Web.Mylib Web.Mylib.ModuleA Web.Mylib.ModuleB build-depends: base >= 4 && <= 5 , [other dependencies of the library] executable mylib-commandline hs-source-dirs: mylib-commandline main-is: Main.hs other-modules: Web.Mylib.Commandline.Main Web.Mylib.Commandline.Arguments build-depends: base >= 4 && <= 5 , mylib , [other depencencies for the CLI] executable mylib-server hs-source-dirs: mylib-server main-is: Server.hs other-modules: Web.Mylib.Server.Main build-depends: base >= 4 && <= 5 , mylib , warp >= X.X , [other dependencies for the server]

cabal build construirá la biblioteca y los dos ejecutables sin compilación doble de la biblioteca, ya que cada uno está en sus propios hs-source-dirs y los ejecutables dependen de la biblioteca.

Aún puede ejecutar los ejecutables con runghc desde la raíz del proyecto, usando el runghc -i para indicar dónde buscará los módulos (usando : como separador):

runhaskell -isrc:mylib-commandline mylib-commandline/Main.hs runhaskell -isrc:mylib-server mylib-server/Server.hs

De esta manera, puede tener un diseño limpio, ejecutables con módulos auxiliares, y todo funciona aún con runhaskell / runghc y ghci . Para evitar escribir esta bandera repetidamente, puede agregar algo similar a

:set -isrc:mylib-commandline:mylib-server

a su archivo .ghci

Tenga en cuenta que a veces se debe dividir el código en paquetes separados, por ejemplo, mylib-commandline , mylib-commandline y mylib-server .