Transcript
Page 1: Start haskell zipper

LLeeaarrnn yyoouu aa HHaasskkeellll

ffoorr GGrreeaatt GGoooodd!!

ZZiippppeerr

13年1月20日日曜日

Page 2: Start haskell zipper

WWhhoo??

•・ 島崎抄子•・ @@sshhookkooss•・ ccyybbeerraaggeenntt

13年1月20日日曜日

Page 3: Start haskell zipper

IInnttrroodduuccttiioonn

TTrreeee→要素を気軽に変更

FFiillee SSyysstteemm→ファイルの操作

13年1月20日日曜日

Page 4: Start haskell zipper

TTrreeee

13年1月20日日曜日

Page 5: Start haskell zipper

TTrreeee

data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Show)

13年1月20日日曜日

Page 6: Start haskell zipper

TTrreeee

GGOOAALL::WW→PP

13年1月20日日曜日

Page 7: Start haskell zipper

TTrreeeefreeTree :: Tree CharfreeTree = Node 'P' (Node 'O' (Node 'L' (Node 'N' Empty Empty) (Node 'T' Empty Empty) ) (Node 'Y' (Node 'S' Empty Empty) (Node 'A' Empty Empty) ) ) (Node 'L' (Node 'W' (Node 'C' Empty Empty) (Node 'R' Empty Empty) ) (Node 'A' (Node 'A' Empty Empty) (Node 'C' Empty Empty) ) )

13年1月20日日曜日

Page 8: Start haskell zipper

TTrreeee

changeToP :: Tree Char -> Tree CharchangeToP (Node x l (Node y (Node _ m n) r)) =

    Node x l (Node y (Node 'P' m n ) r)

RRiigghhtt→LLeefftt→PP

13年1月20日日曜日

Page 9: Start haskell zipper

TTrreeee

進路をリストで指定→要素をPP

data Direction = L | R deriving (Show) type Directions = [Direction]

changeToP :: Directions -> Tree Char -> Tree Char

changeToP (L:ds) (Node x l r) = Node x (changeToP ds l) r changeToP (R:ds) (Node x l r) = Node x l (changeToP ds r) changeToP [] (Node _ l r) = Node 'P' l r

13年1月20日日曜日

Page 10: Start haskell zipper

TTrreeee

elemAt :: Directions -> Tree a -> a

elemAt (L:ds) (Node _ l _) = elemAt ds l

elemAt (R:ds) (Node _ _ r) = elemAt ds r

elemAt [] (Node x _ _) = x

確認用目的地の要素を返す関数

13年1月20日日曜日

Page 11: Start haskell zipper

TTrreeee

要素の更新を、何度も効率よくできるよう部分木から近場の部分木へ切り替えたい!

13年1月20日日曜日

Page 12: Start haskell zipper

TTrreeee

道しるべを残すBBrreeaaddccrruummbbに辿った方向�を追加

type Breadcrumbs = [Direction]

goLeft :: (Tree a, Breadcrumbs) -> (Tree a, Breadcrumbs) goLeft (Node _ l _, bs) = (l, L:bs)

goRight :: (Tree a, Breadcrumbs) -> (Tree a, Breadcrumbs) goRight (Node _ _ r, bs) = (r, R:bs)

13年1月20日日曜日

Page 13: Start haskell zipper

TTrreeee

( Node 'A' (Node 'A' Empty Empty) (Node 'C' Empty Empty) , [R, R]) :: (Tree a, Breadcrumbs)

13年1月20日日曜日

Page 14: Start haskell zipper

TTrreeee

1133章で定義した x -: f = f x を使い美�しく書ける

ghci> goLeft (goRight (freeTree, []))

!

ghci> (freeTree, []) -: goRight -: goLeft

実行結果:(Node 'W' (Node 'C' Empty Empty) (Node 'R' Empty Empty),[L,R])

13年1月20日日曜日

Page 15: Start haskell zipper

TTrreeee

木の情報すべてを持ちたい!!!!

13年1月20日日曜日

Page 16: Start haskell zipper

TTrreeee

辿らなかった部分木の情報も残す

data Crumb a = LeftCrumb a (Tree a) | RightCrumb a (Tree a)

    deriving (Show)

type Breadcrumbs a = [Crumb a]

goLeft :: (Tree a, Breadcrumbs a) -> (Tree a, Breadcrumbs a) goLeft (Node x l r, bs) = (l, LeftCrumb x r:bs)

goRight :: (Tree a, Breadcrumbs a) -> (Tree a, Breadcrumbs a)

goRight (Node x l r, bs) = (r, RightCrumb x l:bs)

13年1月20日日曜日

Page 17: Start haskell zipper

TTrreeee

情報がある→上へ戻れる!

goUp :: (Tree a, Breadcrumbs a) -> (Tree a, Breadcrumbs a) goUp (t, LeftCrumb x r:bs) = (Node x t r, bs)goUp (t, RightCrumb x l:bs) = (Node x l t, bs)

13年1月20日日曜日

Page 18: Start haskell zipper

TTrreeee

TTrreeee aa と BBrreeaaddCCrruummbbのペアは、元の木の状態を持ちつつ、どの部分木に注目しているのかわかる!ZZiippppeerrで定義

type Zipper a = (Tree a, Breadcrumbs a)

13年1月20日日曜日

Page 19: Start haskell zipper

TTrreeee注目している部分木のルートの書き換えができる

modify :: (a -> a) -> Zipper a -> Zipper a

modify f (Node x l r, bs)=(Node (f x ) l r, bs)

modify f (Empty, bs) = (Empty, bs)

13年1月20日日曜日

Page 20: Start haskell zipper

TTrreeee

LLeefftt→RRiigghhtt→PPに要素を変更のあとに、ひとつ上の要素をXXに変更したい!

ghci> let newFocus =

(freeTree, []) -: goLeft -: goRight -: modify (\_ -> 'P')

ghci> let newFocus2 = newFocus -: goUp -: modify (\_ -> 'X')

13年1月20日日曜日

Page 21: Start haskell zipper

TTrreeee

注目している部分木の置き換えもシンプルなコードでできる

attach :: Tree a -> Zipper a -> Zipper a

attach t (_, bs) = (t, bs)

13年1月20日日曜日

Page 22: Start haskell zipper

TTrreeeeトップへ戻る

ggooUUppを、道しるべがなくなるまで再帰

topMost :: Zipper a -> Zipper a

topMost (t, []) = (t, [])

topMost z = topMost (goUp z)

13年1月20日日曜日

Page 23: Start haskell zipper

LLiisstt

LLiissttをZZiippppeerrに!

(注目している要素、辿ってきた要素)

13年1月20日日曜日

Page 24: Start haskell zipper

LLiisstt

LLiissttもZZiippppeerrで作ってみる!type ListZipper a = ([a], [a])

goForward :: ListZipper a -> ListZipper a

goForward (x:xs, bs) = (xs, x:bs)

goBack :: ListZipper a -> ListZipper a

goBack (xs, b:bs) = (b:xs, bs)

13年1月20日日曜日

Page 25: Start haskell zipper

FFiillee SSyysstteemm

13年1月20日日曜日

Page 26: Start haskell zipper

FFiillee SSyysstteemmtype Name = String

type Data = String

data FSItem = File Name Data | Folder Name [FSItem]

deriving (Show)

FFiillee・・・名前がついていて、データが入�っている

FFoollddeerr・・・名前がついていて、複数のファイルやフォルダをアイテムとして含む

13年1月20日日曜日

Page 27: Start haskell zipper

FFiillee SSyysstteemm

myDisk :: FSItem

myDisk = Folder "root" [File "goat_yelling_like_man.wmv" "baaaaaa"

, File "pope_time.avi" "god bless"

, Folder "pics"

[File "ape_throwing_up.jpg" "bleargh"

, File "watermelon_smash.gif" "smash!!"

, File "skull_man(scary).bmp" "Yikes!"

]

, File "dijon_poupon.doc" "best mustard"

, Folder "programs"

[File "fartwizard.exe" "10gotofart"

, File "owl_bandit.dmg" "mov eax, h00t"

, File "not_a_virus.exe" "really not a virus"

, Folder "source code"

[File "best_hs_prog.hs" "main = print (fix error)"

, File "random.hs" "main = print 4"]

]

] 13年1月20日日曜日

Page 28: Start haskell zipper

Folder1

File2Folder2 File1

File3 Folder3

FFiilleeは空の木のようなもの

13年1月20日日曜日

Page 29: Start haskell zipper

FFiillee SSyysstteemm

data FSCrumb = FSCrumb Name [FSItem] [FSItem] deriving (Show)

type FSZipper = (FSItem, [FSCrumb])

NNaammee::親フォルダ名[[FFSSIItteemm]]::前のアイテムのリスト [[FFSSIItteemm]]::後ろのアイテムのリスト

(注目しているアイテム、道しるべのリスト)

13年1月20日日曜日

Page 30: Start haskell zipper

Folder1

File2Folder2 File1

File3 Folder3

注目:FFoollddeerr11前のアイテム:FFoollddeerr22の情報等後ろのアイテム::なし

13年1月20日日曜日

Page 31: Start haskell zipper

FFiillee SSyysstteemm

fsUp :: FSZipper -> FSZipperfsUp (item, FSCrumb name ls rs:bs) =

  (Folder name (ls ++ [item] ++ rs), bs)

注目しているアイテムを、前のアイテムに移す

上の階層に行く

13年1月20日日曜日

Page 32: Start haskell zipper

Folder1

File2Folder2 File1

File3 Folder3 注目:FFoollddeerr22前のアイテム:FFiillee33の情報等後ろのアイテム::FFoollddeerr11の情報等

注目:FFoollddeerr11前のアイテム:FFiillee22の情報等後ろのアイテム::なし

13年1月20日日曜日

Page 33: Start haskell zipper

FFiillee SSyysstteemm

fsTo :: Name -> FSZipper -> FSZipper

fsTo name (Folder folderName items, bs) =

let (ls, item:rs) = break (nameIs name) items

in (item, FSCrumb folderName ls rs:bs)

nameIs :: Name -> FSItem -> BoolnameIs name (Folder folderName _) = name == folderName

nameIs name (File fileName _) = name == fileName

注目しているIItteemmを変更

13年1月20日日曜日

Page 34: Start haskell zipper

FFiillee SSyysstteemm

fsRename :: Name -> FSZipper -> FSZipperfsRename newName (Folder name items, bs) = (Folder newName

items, bs)

fsRename newName (File name dat, bs) = (File newName dat, bs)

RReennaammee

13年1月20日日曜日

Page 35: Start haskell zipper

FFiillee SSyysstteemm

fsNewFile :: FSItem -> FSZipper -> FSZipper

fsNewFile item (Folder folderName items, bs) =

(Folder folderName (item:items), bs)

NNeewwFFiillee

13年1月20日日曜日

Page 36: Start haskell zipper

MMaayybbee!!!!!!goLeft :: Zipper a -> Maybe (Zipper a)

goLeft (Node x l r, bs) = Just (l, LeftCrumb x r:bs)

goLeft (Empty, _) = Nothing

goRight :: Zipper a -> Maybe (Zipper a)

goRight (Node x l r, bs) = Just (r, RightCrumb x l:bs)

goRight (Empty, _) = Nothing

goUp :: Zipper a -> Maybe (Zipper a)

goUp (t, LeftCrumb x r:bs) = Just (Node x t r, bs)

goUp (t, RightCrumb x l:bs) = Just (Node x l t, bs)

goUp (_, []) = Nothing

13年1月20日日曜日


Top Related