Hatena::Grouphaskell

lnzntのHaskell日記 このページをアンテナに追加 RSSフィード

2014年11月24日(月)

モジュール

| 22:00 |  モジュール - lnzntのHaskell日記 を含むブックマーク はてなブックマーク -  モジュール - lnzntのHaskell日記  モジュール - lnzntのHaskell日記 のブックマークコメント

module 宣言

module 宣言の例。

module FileUtils where

この場合、モジモジュールで定義したすべてのエンティティがエクスポートされる。

エクスポートするエンティティの限定する例
module FileUtils (makePath, forceRemove) where

() 内をエクスポートリストと呼ぶ。

インポートしたモジュールのエンティティをすべてまとめて再エクスポートする例
module FileUtils (module Hoge.Fuga) where

import Hoge.Fuga

エクスポートリストに「module モジュール名」と書く。

データコンストラクタをエクスポートする例
data SomeType = ConsA String | ConsB Int

module Hoge (SomeType(ConsA), a, b, c) where

データコンストラクタ型コンストラクタとともにエクスポートリストに書く。

複数エクスポートする場合は以下。

module Hoge (SomeType(ConsA, ConsB), a, b, c) where
または
module Hoge (SomeType(..), a, b, c) where  -- 「..」の場合はすべてのデータコンストラクタを指定したことになる

Main モジュール

module 宣言を省略した場合、ファイルの先頭には以下のようなモジュール宣言が補われる。

module Main (main) where

import 宣言

import 宣言の例

import Hoge.Fuga
特定のエンティティをインポートする例
import Hoge.Fuga (foo, bar)

() 内をインポートリストと呼ぶ。

データコンストラクタのインポートの書式はエクスポートと同様。

hiding 構文
import Hoge.Fuga hiding (baz)

特定のエンティティのインポートを防止する。

qualified 構文
import qualified Hoge.Fuga

エンティティが完全修飾名でのみインポートされる。

as 構文
import HogeHogeHoge.FugaFugaFuga as Hoga

as により一時的な別の完全修飾名を使えるようになる。

型クラス

| 19:09 |  型クラス - lnzntのHaskell日記 を含むブックマーク はてなブックマーク -  型クラス - lnzntのHaskell日記  型クラス - lnzntのHaskell日記 のブックマークコメント

型と型クラス。自分には難解です。

とりあえず、参考書籍見ながら勉強したことをメモしておく。

続きを読む

| 16:48 |  型 - lnzntのHaskell日記 を含むブックマーク はてなブックマーク -  型 - lnzntのHaskell日記  型 - lnzntのHaskell日記 のブックマークコメント

型と型クラス。自分には難解です。

とりあえず、参考書籍見ながら勉強したことをメモしておく。

----

続きを読む

Haskell で 初めての FizzBuzz

| 11:07 |  Haskell で 初めての FizzBuzz - lnzntのHaskell日記 を含むブックマーク はてなブックマーク -  Haskell で 初めての FizzBuzz - lnzntのHaskell日記  Haskell で 初めての FizzBuzz - lnzntのHaskell日記 のブックマークコメント

基本構文もわかったし、そろそろ FizzBuzz が書けるのでは、と書いてみた。

fizzBuzz :: [Int] -> [String]

fizzBuzz ns = map fizzBuzz' ns
              where
                fizzBuzz' n
                    | n `mod` 15 == 0 = "FizzBuzz"
                    | n `mod`  3 == 0 = "Fizz"
                    | n `mod`  5 == 0 = "Buzz"
                    | otherwise       = show n

main = do
    print $ fizzBuzz [1..100]

ここで fizzBuzz ns の ns が不要であることに気付いたので削る。

fizzBuzz :: [Int] -> [String]

fizzBuzz = map fizzBuzz'
           where
             fizzBuzz' n
                 | n `mod` 15 == 0 = "FizzBuzz"
                 | n `mod`  3 == 0 = "Fizz"
                 | n `mod`  5 == 0 = "Buzz"
                 | otherwise       = show n

main = do
    print $ fizzBuzz [1..100]

参考書籍によると、このように関数を関数で定義するのを「ポイントフリースタイル」というらしい。ここでいう「ポイント」は「.」でなく「圏論(数学の一分野:category theory)」の用語で Haskell でいう値のことらしい。(???まったくわからない。。。)

しげしげ、見ていると fizzBuzz' がうざい。本来こっちが主役の関数で map はその頭を修飾しているだけのようなので書き直す。(自分の考えが手続き的なので「map する」に囚われすぎた?)

fizzBuzz :: Int -> String

fizzBuzz n | n `mod` 15 == 0 = "FizzBuzz"
           | n `mod`  3 == 0 = "Fizz"
           | n `mod`  5 == 0 = "Buzz"
           | otherwise       = show n

main = do
    print $ map fizzBuzz [1..100]

こっちのがいい気がする。

「map fizzBuzz」を一関数にまとめたければ、

fizzBuzzMap = map fizzBuzz
    :
    print $ fizzBuzzMap [1..100]

とすればいい。

対比の Ruby版。

#!/usr/bin/env ruby
# -*- coding: UTF-8 -*-

fizzBuzz = -> n do
              n % 15 == 0 ? "FizzBuzz" :
              n %  3 == 0 ? "Fizz"     :
              n %  5 == 0 ? "Buzz"     :
                            "#{n}"
           end

p (1..100).map &fizzBuzz

「map &fizzBuzz」をまとめるにはメソッド等を定義する。以下ではラムダを使う。

fizzBuzzMap = -> ns { ns.map &fizzBuzz }

p fizzBuzzMap.(1..100)