play2.0を実行
$export PATH=$PATH:/usr/local/play2.0
$play
こんなエラーが出るので
Unable to access jarfile /usr/local/play2.0/framework/sbt/sbt-launch.jar
https://gist.github.com/1390651にある内容でplayを更新。
$ vi /usr/local/play2.0/play
再度$play
::::::::::::::::::::::::::::::::::::::::::::::
:: UNRESOLVED DEPENDENCIES ::
::::::::::::::::::::::::::::::::::::::::::::::
:: play#console_2.9.1;2.0-SNAPSHOT: not found
::::::::::::::::::::::::::::::::::::::::::::::
今ここorz
play2.0をゲットする
$mkdir /usr/local/play2.0/
$cd /usr/local/play2.0/
$git clone https://github.com/playframework/Play20.git play2.0
sslがどーたらこーたらいわれたらこう。
$ vi .gitconfig
[http]
sslVerify = false
playframework with scalaでjoda-time
を使おうとしたらこんなエラー
error while loading DateTime, Missing dependency 'class org.joda.convert.FromString',
ここに書いてあるけど
http://groups.google.com/group/play-framework/browse_thread/thread/b448295a3d096b22
http://sourceforge.net/projects/joda-convert/files/joda-convert/
からjoda-convert.jarをダウンロードして%PLAY_HOME%/frameworklibの下に保存すると動く。
Real World Haskell 第4章練 習問題 続き
4.1 asInt_fold マイナス対応
import Data.Char asInt_fold :: String -> Int asInt_fold ('-':xs) = -1 * asInt_fold(xs) asInt_fold xs = foldl step 0 xs where step acc x = acc * 10 + (digitToInt x)
4.2 エラー処理
オーバーフローしたときの処理が悩んだけど、前回の結果と比べて値が小さくなった場合にオーバーフローとして処理するように実装。
import Data.Char asInt_fold :: String -> Int asInt_fold [] = error "asInt_fold required argument" asInt_fold ('-':xs) | xs == "" = error "asInt_fold not allwoed only sigin" | otherwise = -1 * asInt_fold(xs) asInt_fold xs = foldl step 0 xs where step acc x | isDigit x = let acc' = acc * 10 + (digitToInt x) in if acc'> acc then acc' else error "overfllow!" | otherwise = error "as_Int_fold only allowed digit or sigin"
4.3 Either
case 〜 of ってかっこいい。
import Data.Char type ErrorMessage = String asInt_fold :: String -> Either ErrorMessage Int asInt_fold [] = Left "asInt_fold required argument" asInt_fold ('-':xs) | xs == "" = Left "asInt_fold not allwoed only sigin" | otherwise = case asInt_fold xs of Right rs -> Right (-1 * rs) Left rs -> Left rs asInt_fold xs = foldl step (Right 0) xs where step (Right acc) x | isDigit x = let acc' = acc * 10 + (digitToInt x) in if acc'> acc then Right acc' else Left "overfllow!" | otherwise = Left "as_Int_fold only allowed digit or sigin" step (Left acc) _ = Left acc
4.4 my concat
foldr_concat ::[[a]] -> [a] foldr_concat (x:xs) = foldr step x xs where step xs x = x ++ xs
4.4 takeWhileの2パターンの実装
myTakeWhile :: (a -> Bool) -> [a] -> [a] myTakeWhile p (x:xs) | p x = x : myTakeWhile p xs | otherwise = [] foldrTakeWhile :: (a -> Bool) -> [a] -> [a] foldrTakeWhile p xs = foldr step [] xs where step x acc | p x = x : acc | otherwise = []
4.6 groupByを畳み込みで実現
foldGroupBy :: (a -> a -> Bool) -> [a] -> [[a]] foldGroupBy p xs = foldl step [] xs where step [] x = [x] : [] step acc x | p (head (last acc)) x = (init acc) ++ [((last acc) ++ [x])] | otherwise = acc ++ [[x]]
うーん、力技だなぁ。。
4.7 各種関数を畳み込みで実現
myAny :: (a -> Bool) ->[a] -> Bool myAny p xs = foldr step False xs where step x f | f = f | otherwise = p x myWords :: String -> [String] myWords xs = foldr step [] xs where step x ys@(y:tail) | elem x [' ', '\r', '\n'] = [] :ys | otherwise = (x : y) : tail step x [] = [[x]] myUnlines :: [String] -> String myUnlines xs = foldr step "" xs where step x acc = x ++ "\n" ++ acc
cycleはあきらめる。普通にやったらこんな感じ
myCycle :: [a] -> [a] myCycle xs = xs ++ myCycle xs
foldrは有限回数のループ(?)だから無限リストをあらわすのには向いていない。
無理やりやればできないことは無いだろうけど。。
原帰納的
Real World Haskellによると、foldrを使って表現できる関数を原始帰納的というらしいです。
結構な数の関数が原始帰納的らしく、本ではfilterの例がありました。
久しぶりにscalaでやってみたらこんな感じ。
scala> List(1, 2, 3).foldRight(Nil: List[Int]){(x, xs) => if (x %2 == 0) xs else x::xs} res29: List[Int] = List(1, 3)
(1 :: (3 :: Nil))
ちなみにfoldLeftだとListが逆になっちゃう。
scala> List(1, 2, 3).foldLeft(Nil: List[Int]){(xs, x) => if (x %2 == 0) xs else x::xs} res31: List[Int] = List(3, 1)
(3 :: (1 :: Nil))
forでぐるぐる回す処理を書いたときはちゃんと関数脳使ってるか確認したほうがよさげ。。
以下適当に実験
List(1, 2, 3) ++ List(4, 5, 6)
scala> List(1, 2, 3).foldRight(List(4, 5, 6)){_ :: _} res35: List[Int] = List(1, 2, 3, 4, 5, 6)
List(1, 2, 3) map { _ + 1}
scala> List(1, 2, 3).foldRight(Nil:List[Int]){(x, xs) => ( x + 1) :: xs } res46: List[Int] = List(2, 3, 4)
foldLeftだけど。。
List(1, 2, 3) reverse
scala> List (1, 2, 3).foldLeft(Nil:List[Int]){(xs, x) => x::xs} res5: List[Int] = List(3, 2, 1)
ちょっと強引だけど
List(1, 2, 3) contains(2)
scala> List(1, 2, 3).foldRight(false){(x, xs) => xs || (x == 2)} res60: Boolean = true
もちろん性能悪いです。こんなのでも原始帰納的といえるのかなぁ。
cygwinでsbtするとUnable to access jarfile・・・
参考にさせていただいたブログ
http://d.hatena.ne.jp/todomasa/20100909/1284009806
リンク先のブログに書いてありますが、windowsのパスの形式で記述しないといけないらしいです。
java -Xmx512M -jar C:\\program\\cygwin\\usr\\local\\bin\\sbt-launch.jar "$@"