Lispのassocみたいなもの
assoc :: Eq a => a -> [(a, b)] -> Maybe (a, b) assoc itm [] = Nothing assoc itm lst = if (fst tpl) == itm then Just tpl else assoc itm $ tail lst where tpl = head lst
追記
畳込関数を使った方が分かり易い
assoc :: Eq a => a -> [(a,b)] -> Maybe (a, b) assoc itm lst = foldr (¥(k, v) acc -> if k == itm then Just (k,v) else acc) Nothing xs
畳込関数foldrとfoldl
右畳み込み関数foldrは次の様な挙動をする。
ghci> foldr f acc xs (※xs = [x0, x1, x2, x3, x4]とする) f x4 (f x3 (f x2 (f x1 (f x0 acc))))
また、左畳み込み関数foldlは次のような挙動をする。
ghci> foldl f acc xs (※xs = [x0, x1, x2, x3, x4]とする) f (f (f (f (f acc x0) x1) x2) x3) x4
では、xsが無限リストの場合にどのように評価が行われるのか?
以下例、
ghci> foldr (&&) True (repeat False) False && (False && … (False (False && (False && True)))…) この場合、関数(&&)は第一引数がFalseの場合、第二引数を評価しない。 従って、畳み込みは無限に行われることなくFalseと評価される。 ghci> foldl (&&) True (repeat False) (…((((True && False) && False) && False) && False) … ) 左畳み込みの場合は無限に評価され続ける。
lambda関数のつくりかた
メモ
a = ->(x){x*2} b = lambda{|x| x*3} a.(3) #=> 6 b.(3) #=> 9
CentOSにHaskell開発環境を構築してみる
最近Haskellを勉強しているのですが、開発環境をVM上にまとめてしまおうということでやってみました。
ghcをインストール
現時点で最新のghc7.6.3のソースURLをGHC: Download version 7.6.3からとってくる。
$ wget http://www.haskell.org/ghc/dist/7.6.3/ghc-7.6.3-x86_64-unknown-linux.tar.bz2 $ tar xjvf ghc-7.6.3-x86_64-unknown-linux.tar.bz2 $ cd ghc-7.6.3/ $ ./configure --prefix=/usr/local/haskell/ghc/7.6.3 $ sudo make install
Haskell Platformをインストール
現時点で最新のhaskell-platform-2013.2.0.0のソースURLをHaskell Platform for Linuxから取ってくる。
$ wget http://www.haskell.org/platform/download/2013.2.0.0/haskell-platform-2013.2.0.0.tar.gz $ tar xzvf haskell-platform-2013.2.0.0.tar.gz $ cd haskell-platform-2013.2.0.0/ gmpとopenGL関連でエラーが出たので入れておきます $ sudo yum -y install gmp-devel freeglut-devel $ ./configure --prefix=/usr/local/haskell/haskell-platform/2013.2.0.0 $ make $ sudo make install
パスを通す
最後に、ghcとHaskell Platformへとパスを通しておきます。
~/.bashrcに以下を追記
export PATH=/usr/local/haskell/haskell-platform/2013.2.0.0/bin:/usr/local/haskell/ghc/7.6.3/bin:$PATH
追記
sudo cabal install cabal-install --global
をするためにはパスをsudoに引継ぐ必要がありました。
こちらを参照→CentOS で sudo 時に実行ユーザーのPATHを引き継ぐ - Qiita
もっといい方法はないものか…
for...in文とeachイテレータのスコープ
array = [1,2,3,4,5] for x in array puts x end array.each do |y| puts y end puts x #=>5 puts y #=>エラーを返す
eachメソッド内のブロックは独自のスコープを持つ