Scala でなにか書くつもりだったのに、気づいたら Haskell で Unlambda を書いていた
あ、これを Scala に移植してみればいいのか。
とりあえず、.x, r, s, k, i だけ。d とか c はどうすればいいのかなぁ。
import Data.Char (isSpace) data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving Show data Func = Func (Func -> IO Func) apply :: Func -> Func -> IO Func apply (Func f) g = f g >>= return p :: Char -> Func p c = Func (\f -> putChar c >> return f) r :: Func r = Func (\f -> putChar '\n' >> return f) s, k, i :: Func s = Func (\f -> return $ Func (\g -> return $ Func (\h -> do i <- apply f h j <- apply g h apply i j))) k = Func (\f -> return $ Func (\g -> return f)) i = Func (\f -> return f) parse :: String -> Tree Func parse s = case parse' s of Just (t, []) -> t Just (t, rest) | all isSpace rest -> t _ -> error "parse error" parse' :: String -> Maybe (Tree Func, String) parse' ('`':cs) = do (l, cs') <- parse' cs (r, cs'') <- parse' cs' Just (Branch l r, cs'') parse' ('.':c:cs) = Just (Leaf (p c), cs) parse' ('r':cs) = Just (Leaf r, cs) parse' ('s':cs) = Just (Leaf s, cs) parse' ('k':cs) = Just (Leaf k, cs) parse' ('i':cs) = Just (Leaf i, cs) parse' (c:cs) | isSpace c = parse' cs parse' _ = Nothing eval :: Tree Func -> IO Func eval (Leaf f) = return f eval (Branch l r) = do f <- eval l g <- eval r apply f g
http://hw001.gate01.com/eggplant/tcf/unlambda/tutorial.html と 翻訳:プログラミング言語Unlambda を参考にさせてもらいました。他は特に見てないので、ぐぐってみればもっとかっこいい書き方があるに違いない。Haskell で Unlambda なんて、やってる人はごまんといるよなぁ、多分。
実行例
*Main> eval $ parse "`r`````````````.H.e.l.l.o.,. .w.o.r.l.d.!.a" Hello, world! *Main> eval $ parse "```s``si`k.*`ki```s``s`k``s`ksk``sii``si`k``s``s`kski``s``s`ksk``s``s`kski" ************************************(中略)****Main>
Func はひょっとしてモナドにできたりしないかなぁ。s 書いててヤになってきたので。