haskell-jp / beginners #19 at 2022-01-24 19:21:06 +0900

はじめまして。
以下のHLSのエラーについてご質問させてください。
[cradle] [E] Multi Cradle: No prefixes matched

ソースコードはこちらです。app/AST.hsを開くと発生します。
https://github.com/htlsne/misc/tree/arithmetic-expression/haskell/arithmetic_expression

HLSのバージョンは以下です。
haskell-language-server version: 1.5.1.0 (GHC: 8.10.7)

以下を試しましたが解決しませんでした。
1. gen-hie > hie.yamlを実行してhie.yamlを生成したのですが、 エラーは消えませんでした。(
2. hie.yamlにAST.hsを追加したところ、AST.hsのエラーは消えました。しかし今度はMain.hsで`[not found] [E] Could not find module 'AST'` というエラーが出ています。(
どのようにしたら解決できるでしょうか。また、そもそもモジュールの作り方はこれで合っているのでしょうか。
既出の質問のようなのですが、解決できなかったためご相談させてください。
Cabalドキュメンテーションの7.2.9節

Note
 
Every module in the package must be listed in one of other-modules, library:exposed-modules or executable:main-is fields.
とあるように、Cabalを使うならモジュール名は全て .cabal ファイルに書かないとマズイっぽくて、そんで、とりあえず executable arithmetic-expressionに付属して他のlibraryやexecutableから参照されないものは その executableの other-modules に書くことになってるっぽいので、Cabalファイルを


-- A longer description of the package.
-- description:

-- A URL where users can report bugs.
-- bug-reports:

-- The license under which the package is released.
-- license:
author:             htlsne
maintainer:         

-- A copyright notice.
-- copyright:
-- category:
extra-source-files: CHANGELOG.md

executable arithmetic-expression
    main-is:          Main.hs

    -- Modules included in this executable, other than Main.
    other-modules:   AST

    -- LANGUAGE extensions used by modules in this package.
    -- other-extensions:
    build-depends:
        base ^>=4.14.3.0,
        parsec ^>= 3.1.15.0
    hs-source-dirs:   app
    default-language: Haskell2010

に直して gen-hie > hie.yaml を実行してみたところ、当方のEmacs環境上では動いているように見えますが、自信はありません…
ちなみにこのcabalファイルで gen-hie > hie.yaml すると

cradle:
  cabal:
    - path: "app/Main.hs"
      component: "arithmetic-expression:exe:arithmetic-expression"

    - path: "app/AST.hs"
      component: "arithmetic-expression:exe:arithmetic-expression"

になります。
ありがとうございます。
なるほど、すべてのモジュールを記載する必要があるのですね…。
other-modulesに記載したところ、hie.yamlを作成しなくてもエラーは出なくなったようでした。

これってCabal特有の話なのでしょうか。
Stackでもすべてのモジュールを追加する必要があるのでしょうか?

また、hpackというものを見つけたのですが、皆さんこのようなツールを使って解決されているのでしょうか。
ご確認なさったかもしれませんが、hpackは package.yaml というyaml形式のファイルを変換して <package-name>.cabal ファイル群を生成するツールです。このhpackには、cabalファイルを生成する際に、`exposed-modules` か other-modules の一方が未指定で他方が指定済みの場合、取り残された .hs ファイルを全て未指定の方(libraryの場合に両方未指定のなら exposed の方)に突っ込む、という機能があります。というかこれが最も主要な機能の一個ですね。ですので、package.yaml+hpackを使うなら、other-modulesにいちいち書く必要はないわけです。

ところで、Stackは、自動的にhpackを呼びます。そうすることで、package.yamlファイルを使っても.cabalファイルを使ってもパッケージを作成できるようになっています。ということは、.cabalファイルを使ってStackを使うなら、すべてのモジュールをいちいち書く必要がありますが、package.yamlを使う場合にはその必要はないわけです。
なるほどです、納得できました。

Stackを使うにせよCabalを使うにせよ、hpackを使う方向で試してみたいと思います。
丁寧に説明いただきありがとうございました!
cabalは勝手にhpackを呼んではくれないので、cabal+hpackを自動化するならちょっと頑張らないといけないっぽいですけどね…。なんにせよ、お役に立てたならよかったです!