2012年1月14日土曜日

haskellを勉強してみる

http://www.haskell.org/haskellwiki/Meta-tutorial

2. You have programmed in other functional languages before
から
A brief introduction to Haskell
を選択してやってみる。


1. Background
1990. Haskell 1.0
最近はやりのだと思っていたら、意外と古くて驚き。


2. Haskell features

Immutable variables by default (mutable state programmed via monads)
不変

Pure by default (side effects are programmed via monads)
純粋

Lazy evaluation: results are only computed if they're required (strictness optional)
遅延評価

Everything is an expression


First-class functions: functions can be defined anywhere, passed as arguments, and returned as values.
第一級関数
関数がファーストクラスとして使えるということでしょうか。

Both compiled and interpreted implementations available
コンパイラとインタプリタの実装がある。

Full type inference -- type declarations optional
型推論

Pattern matching on data structures -- data structures are first class!
パターンマッチ

Parametric polymorphism
パラメーターポリモーフィズム
パラメータで実行される関数が変わるよ、ということでしょうか。

Bounded parametric polymorphism
境界があるよ。
うーん、これは良く分からない。
というか英語で読むことに慣れていないからニュアンスがわからないのだと思う。

3. Basics

Prelude> let x = 3 + 4
Prelude> :t x
x :: Integer
Prelude> x
7
Prelude> x + 4
11
Prelude> let x = 4 in x + 3
7
ん?
Lispでいう
(let ((x 4))
 (+ x 3))
みたいなものかな?1行で書かないといけないのでinが違和感ある。

Prelude> Char.toUpper "x"
<interactive>:1:13:
    Couldn't match expected type `Char' against inferred type `[Char]'
    In the first argument of `GHC.Unicode.toUpper', namely `"x"'
    In the expression: GHC.Unicode.toUpper "x"
    In the definition of `it': it = GHC.Unicode.toUpper "x"
間違えた。

Prelude> Char.toUpper 'x'
'X'
OK。

Prelude> :m + Char
Prelude Char> toUpper 'y'
'Y'

Lispでいうin-packageみたいなもの?

Prelude Char> :m
Prelude>
戻りました。


Prelude> :t (*)
(*) :: (Num a) => a -> a -> a
(*)はaを受け取り、aを受け取り、aを返す。aはNumクラスのa。と読めばよいのでしょうか。
2個の数値を受け取って数値を返す。
ということは * 3 も関数?

Prelude> :t * 3
<interactive>:1:0: parse error on input `*'
Prelude>
だめですね。
Prelude> :t (* 3)
(* 3) :: (Num a) => a -> a
Prelude>
あ、できた。

ということは
Prelude> (* 3) 2
6
なるほど。


Prelude> (2.3 :: Double) * (5 :: Int)
<interactive>:1:19:
    Couldn't match expected type `Double' against inferred type `Int'
    In the second argument of `(*)', namely `(5 :: Int)'
    In the expression: (2.3 :: Double) * (5 :: Int)
    In the definition of `it': it = (2.3 :: Double) * (5 :: Int)
*が受け取る引数は同じ型を想定しているため、DoubleとIntだと計算ができない。

Prelude> (2.3 :: Double) * fromIntegral (5 :: Int)
11.5
fromIntegralはIntをNumに変換する関数。
NumからDoubleに型変換されて計算できている模様。

Prelude> :t (* (2.3:: Double))
(* (2.3:: Double)) :: Double -> Double
今日はここまで。

2012年1月8日日曜日

haskellを始める

インストール
ubuntuなので、sudo apt-get install ghc6 で完了。


emacsの設定
http://projects.haskell.org/haskellmode-emacs/ から2.8.0をダウンロード。
ローカルに展開する。

.emacsに以下の設定を追加。
(add-to-list 'load-path (expand-file-name "~/prog/haskell/haskell-mode-2.8.0"))
(load "haskell-site-file")
(setq haskell-program-name "/usr/bin/ghci")
(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
(add-hook 'haskell-mode-hook 'font-lock-mode)
(add-hook 'haskell-mode-hook 'imenu-add-menubar-index)

M-x run-haskellで起動。

起動直後
--------------------------------------------------------------------
File Edit Options Buffers Tools Errors Complete In/Out Signals Help
;; This buffer is for notes you don't want to save, and for Lisp evaluation.
;; If you want to create a file, visit that file with C-x C-f,
;; then enter the text in that file's own buffer.




-uuu:---F1  *scratch*      All (5,0)      (Lisp Interaction)----1:27午前 Mail---
GHCi, version 6.12.1:
http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude>



-uuu:**-F1  *haskell*      All (5,9)      (Inf-Haskell:run Compilation)----1:27$
Loading /home/shingo/prog/haskell/haskell-mode-2.8.0/inf-haskell.el (source)...\
done

--------------------------------------------------------------------

上のバッファでコードを書いて test.hs で保存。
C-c C-l で転送。

--------------------------------------------------------------------File Edit Options Buffers Tools Errors Complete In/Out Signals Help
foo x y = x + y






-uuu:---F1  test.hs        All (2,0)      (Haskell Ind Doc)----1:28午前 Mail----
GHCi, version 6.12.1:
http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :load "/home/shingo/test.hs"
[1 of 1] Compiling Main             ( /home/shingo/test.hs, interpreted )
Ok, modules loaded: Main.
*Main> foo 1 2
3
*Main>
-uuu:**-F1  *haskell*      All (10,7)     (Inf-Haskell:run Compilation)----1:28$

--------------------------------------------------------------------
今日はここまで。