プログラミングHaskell8章
本の通りにdo記法使うと動かなかったのでbindをつかってせっせと書いた。そのおかげで、←とか>>=見るとラムダ式が意識できるようになってきた。
第14回 関数脳のつくり方 Second Season 〜モナドで悟りをひらく〜
関数型言語で「プログラムの実行順序を保証」したり
import Char type Parser a = String -> [(a,String)] myreturn :: a -> Parser a myreturn v = \inp -> [(v,inp)] myfailure :: Parser a myfailure = \inp -> [] myitem :: Parser Char myitem = \inp -> case inp of [] -> [] (x:xs) -> [(x,xs)] parse :: Parser a -> String -> [(a,String)] parse p inp = p inp (>>==) :: Parser a -> (a -> Parser b) -> Parser b p >>== f = \inp -> case parse p inp of [] -> [] [(v,out)] -> parse (f v) out -- p :: Parser (Char,Char) -- p = myitem >>== \x -> -- myitem >>== \y -> -- myitem >>== \z -> -- myreturn (x,z) (+++) :: Parser a -> Parser a -> Parser a p +++ q = \inp -> case parse p inp of [] -> parse q inp [(v,out)] -> [(v,out)] sat :: (Char -> Bool) -> Parser Char sat p = myitem >>== \x -> if p x then myreturn x else myfailure digit :: Parser Char digit = sat isDigit lower :: Parser Char lower = sat isLower upper :: Parser Char upper = sat isUpper letter :: Parser Char letter = sat isAlpha alphanum :: Parser Char alphanum = sat isAlphaNum char :: Char -> Parser Char char x = sat (== x) string :: String -> Parser String string [] = myreturn [] string (x:xs) = char x >>== \_ -> string xs >>== \_ -> myreturn (x:xs) many :: Parser a -> Parser [a] many p = many1 p +++ myreturn [] many1 :: Parser a -> Parser [a] many1 p = p >>== \v -> many p >>== \vs -> myreturn (v:vs) ident :: Parser String ident = lower >>== \x -> many alphanum >>== \xs -> myreturn (x:xs) nat :: Parser Int nat = many1 digit >>== \xs -> myreturn (read xs) space :: Parser () space = many (sat isSpace) >>== \_ -> myreturn () token :: Parser a -> Parser a token p = space >>== \_ -> p >>== \v -> space >>== \_ -> myreturn v identifer :: Parser String identifer = token ident natural :: Parser Int natural = token nat symbol :: String -> Parser String symbol xs = token (string xs) -- 8-1 -- int :: Parser Int int = char '-' >>== \_ -> nat >>== \n -> myreturn (-n) +++ nat -- -- -- -- 8-2 -- comment :: Parser () comment = string "--" >>== \_ -> many (sat (/= '\n')) >>== \_ -> myreturn () -- -- --