start haskell zipper
TRANSCRIPT
LLeeaarrnn yyoouu aa HHaasskkeellll
ffoorr GGrreeaatt GGoooodd!!
ZZiippppeerr
13年1月20日日曜日
WWhhoo??
•・ 島崎抄子•・ @@sshhookkooss•・ ccyybbeerraaggeenntt
13年1月20日日曜日
IInnttrroodduuccttiioonn
TTrreeee→要素を気軽に変更
FFiillee SSyysstteemm→ファイルの操作
13年1月20日日曜日
TTrreeee
13年1月20日日曜日
TTrreeee
data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Show)
13年1月20日日曜日
TTrreeee
GGOOAALL::WW→PP
13年1月20日日曜日
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日日曜日
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日日曜日
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日日曜日
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日日曜日
TTrreeee
要素の更新を、何度も効率よくできるよう部分木から近場の部分木へ切り替えたい!
13年1月20日日曜日
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日日曜日
TTrreeee
( Node 'A' (Node 'A' Empty Empty) (Node 'C' Empty Empty) , [R, R]) :: (Tree a, Breadcrumbs)
13年1月20日日曜日
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日日曜日
TTrreeee
木の情報すべてを持ちたい!!!!
13年1月20日日曜日
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日日曜日
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日日曜日
TTrreeee
TTrreeee aa と BBrreeaaddCCrruummbbのペアは、元の木の状態を持ちつつ、どの部分木に注目しているのかわかる!ZZiippppeerrで定義
type Zipper a = (Tree a, Breadcrumbs a)
13年1月20日日曜日
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日日曜日
TTrreeee
LLeefftt→RRiigghhtt→PPに要素を変更のあとに、ひとつ上の要素をXXに変更したい!
ghci> let newFocus =
(freeTree, []) -: goLeft -: goRight -: modify (\_ -> 'P')
ghci> let newFocus2 = newFocus -: goUp -: modify (\_ -> 'X')
13年1月20日日曜日
TTrreeee
注目している部分木の置き換えもシンプルなコードでできる
attach :: Tree a -> Zipper a -> Zipper a
attach t (_, bs) = (t, bs)
13年1月20日日曜日
TTrreeeeトップへ戻る
ggooUUppを、道しるべがなくなるまで再帰
topMost :: Zipper a -> Zipper a
topMost (t, []) = (t, [])
topMost z = topMost (goUp z)
13年1月20日日曜日
LLiisstt
LLiissttをZZiippppeerrに!
(注目している要素、辿ってきた要素)
13年1月20日日曜日
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日日曜日
FFiillee SSyysstteemm
13年1月20日日曜日
FFiillee SSyysstteemmtype Name = String
type Data = String
data FSItem = File Name Data | Folder Name [FSItem]
deriving (Show)
FFiillee・・・名前がついていて、データが入�っている
FFoollddeerr・・・名前がついていて、複数のファイルやフォルダをアイテムとして含む
13年1月20日日曜日
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日日曜日
Folder1
File2Folder2 File1
File3 Folder3
FFiilleeは空の木のようなもの
13年1月20日日曜日
FFiillee SSyysstteemm
data FSCrumb = FSCrumb Name [FSItem] [FSItem] deriving (Show)
type FSZipper = (FSItem, [FSCrumb])
NNaammee::親フォルダ名[[FFSSIItteemm]]::前のアイテムのリスト [[FFSSIItteemm]]::後ろのアイテムのリスト
(注目しているアイテム、道しるべのリスト)
13年1月20日日曜日
Folder1
File2Folder2 File1
File3 Folder3
注目:FFoollddeerr11前のアイテム:FFoollddeerr22の情報等後ろのアイテム::なし
13年1月20日日曜日
FFiillee SSyysstteemm
fsUp :: FSZipper -> FSZipperfsUp (item, FSCrumb name ls rs:bs) =
(Folder name (ls ++ [item] ++ rs), bs)
注目しているアイテムを、前のアイテムに移す
上の階層に行く
13年1月20日日曜日
Folder1
File2Folder2 File1
File3 Folder3 注目:FFoollddeerr22前のアイテム:FFiillee33の情報等後ろのアイテム::FFoollddeerr11の情報等
注目:FFoollddeerr11前のアイテム:FFiillee22の情報等後ろのアイテム::なし
13年1月20日日曜日
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日日曜日
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日日曜日
FFiillee SSyysstteemm
fsNewFile :: FSItem -> FSZipper -> FSZipper
fsNewFile item (Folder folderName items, bs) =
(Folder folderName (item:items), bs)
NNeewwFFiillee
13年1月20日日曜日
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日日曜日