読者です 読者をやめる 読者になる 読者になる

Haskell勉強会に参加しました

3/20にjus主催で開催された「Haskellによる関数プログラミング」に参加しました.秋葉原のダイビルに行ったのはVimM以来ですね.

勉強会メモ

  • Haskellは倍精度に特化してチューニングしているので単精度より高速
  • 作ろうとするものの型をまず書くことが重要
  • 高階関数の話として単純なBMI関数からcurry化への流れ
type BMI = Double
type Height = Double
type Weight = Double

bmi (Height, Weight) -> BMI
bmi (h,w) = w / h^2

mkbmi :: Height -> Weight -> BMI
mkbmi h w = bmi (h, w)

mk :: ((Height, Weight) -> BMI) -> Height -> Weight -> BMI
mk bmi h w = bmi (h, w)
-- mkはcurryである
curry :: ((a, b) -> c) -> a -> b -> c
curry f x y = f (x, y)
  • 再帰の心
    • 1歩手前まで完成したと考える
    • 1歩手前がない,あるいは特殊な場合を考える
    • *手続き的*な思考をしない
    • ループを考えてはいけない
    • 値の構成を考える
  • n段の階段の昇りかた
    • 1段か2段ずつ昇れるとき昇りかたは何通り?
    • フィボナッチな問題を見せられて気づく人はすくない
stepWays 0 = 1
stepWays 1 = stepWays 0
stepWays n = stepWays (n-2) + stepWays (n-1)
-- O(c^n) / _ /x uh-oh
  • 再帰って使えない?
    • そんなことはない.式をじっくり眺める.
    • タプリング
stepWays2 :: Integer -> (Integer, Integer)
stepWays2 0 = (1, 1)
stepWays2 n = (b, a+b)
  where
    (a, b) = stepWays2 (n-1)
fastStepWays :: Integer -> Integer
fastStepWays = fst . stepWays2
-- O(n) / _ /x good
fizz, buzz, fizzbuzz :: [String]
fizzbuzz = zipWith f [0..] (zipWith (++) fizz buzz)
  where
    f n "" = show n
    f _ s  = s
fizz cycle (take 3 ("Fizz":repeat "")) -- ["Fizz", "", "", "Fizz", "", ""..]
buzz cycle (take 5 ("Buzz":repeat "")) -- ["Buzz", "", "", "", "", "Buzz", "", "", "", ""..]
main = print $ take 100 (tail fizzbuzz)
  • アクションの合成
(>>) :: IO a -> IO b -> IO b
(>>=) :: IO a -> (a -> IO b) -> IO b
    • (>>)は関数合成(.)と対応している
    • (>>=)は関数適用($)と対応している
      • ただし左右逆
g >> f <--> f . g
x >>= f <--> f $ x
  • テキストファイルからコンソールデモを行うためのアプリケーションSlideShowの実装

つまったこと

SlideShowでは日本語を表示させるために,utf8-stringパッケージを使用するのですが,ghcでコンパイルするときには'--make'オプションをつけないとリンクできないことに気づくのに30分くらいかかってしまいました.

% cat utf8.hs
import qualified System.IO.UTF8 as U

utf8str = "ほげほげ"
main = U.putStrLn utf8str
% runghc utf8.hs
ほげほげ
% ghc -o utf8 utf8.hs
Undefined symbols:
  "___stginit_utf8zmstringzm0zi3zi4_SystemziIOziUTF8_", referenced from:
      ___stginit_Main_ in utf8.o
  "_utf8zmstringzm0zi3zi4_SystemziIOziUTF8_putStrLn_closure", referenced from:
      _Main_main_info in utf8.o
      _Main_main_srt in utf8.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
% ghc --make utf8.hs
[1 of 1] Compiling Main             ( utf8.hs, utf8.o )
Linking utf8 ...
% ./utf8
ほげほげ

# runghcでは動くので気づかなかった.

感想

jus勉強会には初めての参加でしたが,とても楽しめました.講師の山下さん,jusの皆様,ありがとうございました.