計算機科学のブログ

Haskell - コードの整理とプロジェクトのビルド - stackを使ってプロジェクトをビルトする - package.yaml, default-extensions, OverloadedStrings

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)の UNIT6(コードの整理とプロジェクトのビルド)、LESSON 35(stackを使ってプロジェクトをビルトする)、35.6(練習問題)、Q35-1の解答を求めてみる。

軽量マークアップ言語

palindrome-checker/package.yaml

name:                palindrome-checker
version:             0.1.0.0
github:              "githubuser/palindrome-checker"
license:             BSD-3-Clause
author:              "kamimura"
maintainer:          "example@example.com"
copyright:           "2025 kamimura"

extra-source-files:
- README.md
- CHANGELOG.md

# Metadata used when publishing your package
# synopsis:            Short description of your package
# category:            Web

# To avoid duplicated efforts in documentation and dealing with the
# complications of embedding Haddock markup inside cabal files, it is
# common to point users to the README.md file.
description:         Please see the README on GitHub at <https://github.com/githubuser/palindrome-checker#readme>

dependencies:
- base >= 4.7 && < 5
- text

ghc-options:
- -Wall
- -Wcompat
- -Widentities
- -Wincomplete-record-updates
- -Wincomplete-uni-patterns
- -Wmissing-export-lists
- -Wmissing-home-modules
- -Wpartial-fields
- -Wredundant-constraints

default-extensions:
  - OverloadedStrings

library:
  source-dirs: src


executables:
  palindrome-checker-exe:
    main:                Main.hs
    source-dirs:         app
    ghc-options:
    - -threaded
    - -rtsopts
    - -with-rtsopts=-N
    dependencies:
    - palindrome-checker


tests:
  palindrome-checker-test:
    main:                Spec.hs
    source-dirs:         test
    ghc-options:
    - -threaded
    - -rtsopts
    - -with-rtsopts=-N
    dependencies:
    - palindrome-checker

軽量マークアップ言語

palindrome-checker/stack.yaml

# This file was automatically generated by 'stack init'
#
# Some commonly used options have been documented as comments in this file.
# For advanced use and comprehensive documentation of the format, please see:
# https://docs.haskellstack.org/en/stable/yaml_configuration/

# A 'specific' Stackage snapshot or a compiler version.
# A snapshot resolver dictates the compiler version and the set of packages
# to be used for project dependencies. For example:
#
# snapshot: lts-22.28
# snapshot: nightly-2024-07-05
# snapshot: ghc-9.6.6
#
# The location of a snapshot can be provided as a file or url. Stack assumes
# a snapshot provided as a file might change, whereas a url resource does not.
#
# snapshot: ./custom-snapshot.yaml
# snapshot: https://example.com/snapshots/2024-01-01.yaml
snapshot:
  url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/15.yaml

# User packages to be built.
# Various formats can be used as shown in the example below.
#
# packages:
# - some-directory
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
#   subdirs:
#   - auto-update
#   - wai
packages:
- .
# Dependency packages to be pulled from upstream that are not in the snapshot.
# These entries can reference officially published versions as well as
# forks / in-progress versions pinned to a git hash. For example:
#
# extra-deps:
# - acme-missiles-0.3
# - git: https://github.com/commercialhaskell/stack.git
#   commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
#
# extra-deps: []

# Override default flag values for project packages and extra-deps
# flags: {}

# Extra package databases containing global packages
# extra-package-dbs: []

# Control whether we use the GHC we find on the path
# system-ghc: true
#
# Require a specific version of Stack, using version ranges
# require-stack-version: -any # Default
# require-stack-version: ">=3.1"
#
# Override the architecture used by Stack, especially useful on Windows
# arch: i386
# arch: x86_64
#
# Extra directories used by Stack for building
# extra-include-dirs: [/path/to/dir]
# extra-lib-dirs: [/path/to/dir]
#
# Allow a newer minor version of GHC than the snapshot specifies
# compiler-check: newer-minor

コード

palindrome-checker/app/Main.hs

module Main (main) where
import Palindrome(isPalindrome)
import qualified Data.Text.IO as TIO
import Lib(someFunc)
main :: IO ()
main = do
    TIO.putStrLn "Enter a word and I'll let you know if it's a palindrome!"
    text <- TIO.getLine
    let response = if isPalindrome text
                then "it is!"
                else "it's not!"
    TIO.putStrLn response
    someFunc

コード

palindrome-checker/src/Lib.hs

module Lib
    ( someFunc
    ) where

someFunc :: IO ()
someFunc = putStrLn "someFunc"

コード

palindrome-checker/src/Palindrome.hs

module Palindrome(isPalindrome) where

import qualified Data.Text as T
import Data.Char (toLower,isSpace,isPunctuation)

stripWhiteSpace :: T.Text -> T.Text
stripWhiteSpace = T.filter (not . isSpace)

stripPunctuation :: T.Text -> T.Text
stripPunctuation = T.filter (not . isPunctuation)

preProcess :: T.Text -> T.Text
preProcess = stripWhiteSpace . stripPunctuation . T.toLower

isPalindrome :: T.Text -> Bool
isPalindrome text = cleanText == T.reverse cleanText
    where cleanText = preProcess text

入出力結果(Terminal, Zsh)

% stack build                  
palindrome-checker-0.1.0.0: unregistering (local file changes: package.yaml)
palindrome-checker> build (lib + exe) with ghc-9.8.4
Preprocessing library for palindrome-checker-0.1.0.0..
Building library for palindrome-checker-0.1.0.0..
Preprocessing executable 'palindrome-checker-exe' for palindrome-checker-0.1.0.0..
Building executable 'palindrome-checker-exe' for palindrome-checker-0.1.0.0..
palindrome-checker> copy/register
Installing library in /Users/.../palindrome-checker/.stack-work/install/aarch64-osx/e7436b3217cf53d6b9beeebd2bdc5dd8dcab6f8595b8bde259631442ce745f25/9.8.4/lib/aarch64-osx-ghc-9.8.4/palindrome-checker-0.1.0.0-AsDJJAXtgGvCwcL0FmK5ox
Installing executable palindrome-checker-exe in /Users/.../palindrome-checker/.stack-work/install/aarch64-osx/e7436b3217cf53d6b9beeebd2bdc5dd8dcab6f8595b8bde259631442ce745f25/9.8.4/bin
Registering library for palindrome-checker-0.1.0.0..
% stack exec palindrome-checker-exe
Enter a word and I'll let you know if it's a palindrome!
Racecar
it is!
someFunc
%