scalaはPlay frameworkでよく使われているらしい。Railsに似ている。
(javafxの利用も考えてみたが、どうもマイナーなようで、あまり情報が集められない。やはり主流はWEBサーバ用のようだ。)
試しにインストールしてみたが、なかなか一度でうまくはいかない。scalaの特徴を活かした便利なフレームワークではあるが、インストールの敷居はけっこう高いようだ。
いくつかひっかかったところをまとめてみた。
・最新版はplayでなくactivatorというコマンドを使用している。
・typesafe-activator-1.3.5-minimal版のほうでうまくいった。フルセット版(400MB以上ある)だと、すでにあるscalaと競合?したのかうまくいかなかった。
・activator.bat(win版の場合)のあるフォルダのPathを通して再起動。
・コマンドプロンプトで、上記フォルダに移動して、いろいろ操作。
activator newで、簡単にプロジェクタが作成できるようだ。activator uiとすると、WEB上で操作もできるという優れもの。
・eclipseで使えるようにするには、project/plugins.sbtというファイルを作成して、以下の記述をすると使えるようになります。
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0")
これが、なかなかわからなくて、苦労した。
このあと、activator eclipseというコマンドで処理したあと、eclipseを起動して「Existing Projects into Workspace」でワークスペースにインポートすることができる。
2015年7月30日木曜日
2015年7月28日火曜日
Scalaで学ぶ関数脳入門 パーサー2
P333 リスト8の確認
def test(caption:String,data:Stirng){
println(Caption+data)
read (new SimpleLexer(data))
}
def read(lexer:Simplelexer):Unit=lexer.nextToken match= {
case Token(lexer.EOF,value)=>println()
case token:Token=>print(token);read(lexer)
}
case token:Token=>print(token);read(lexer)のところで、再帰を使っている。lexerの中身は、readで処理されるたびに、先頭文字が1文字ずつ削除されていく。print(token)により、token.toStirngがプリントされるということのようだ。
P335 リスト9について
def expression = {
number
nextToken match {
case Token(...
....
ここでは、再帰は見当たらない?一桁数字+一桁数字の単純な式だけの処理をしているということだろうか?
このへんになってくると、パーサーの複雑さを感じる。
*********
いちおう、最後まで全ページを読んでみた。全体的に、関数型に関する記述は少ないので、関数型プログラミングの学習にはあまりならなかったが、基本的な並列処理やパーサの記述がとても参考になった。
def test(caption:String,data:Stirng){
println(Caption+data)
read (new SimpleLexer(data))
}
def read(lexer:Simplelexer):Unit=lexer.nextToken match= {
case Token(lexer.EOF,value)=>println()
case token:Token=>print(token);read(lexer)
}
case token:Token=>print(token);read(lexer)のところで、再帰を使っている。lexerの中身は、readで処理されるたびに、先頭文字が1文字ずつ削除されていく。print(token)により、token.toStirngがプリントされるということのようだ。
P335 リスト9について
def expression = {
number
nextToken match {
case Token(...
....
ここでは、再帰は見当たらない?一桁数字+一桁数字の単純な式だけの処理をしているということだろうか?
このへんになってくると、パーサーの複雑さを感じる。
*********
いちおう、最後まで全ページを読んでみた。全体的に、関数型に関する記述は少ないので、関数型プログラミングの学習にはあまりならなかったが、基本的な並列処理やパーサの記述がとても参考になった。
Scalaで学ぶ関数脳入門 パーサー
P332 リスト7 一から実装した簡単な字句解析器の例が出ていた。説明が簡潔なため、よく考えないとわからなかった。
case class Token(val tokenType:String,val value:String){
override der toString ="["+tokenType+":" "+value+"]"
}
class simpleLexer(input:Stirng){
val OPERATOR="OPERATOR"
val NUMBER="NUMBER"
val EOF="EOF"
var reader =new CarSequenceReader(input)
def netxToken():Token=|
while(!readre.atEnd){
reader.first match {
case c:Char if (c=='+' || c=='-")
=> return new Token(OPERATOR,takeFirst)
case ....................
case c:Char if (c==' ' || c== '\t'...) =>dump
..................
}
.......................
def takeFirst()={
val first =reader.first
reader=reader.drop(1)
first.toString
}
これは、先頭の文字を返すが、その先頭の文字を文字シーケンス(reader)から削除するらしい。
ただ、よくわからないのは、これがdumpの中で使われていて、dumpの返り値はUnitであること。dumpはStringを返すこともあるんだけど、:Unitとすれば、Stringは無視されるんということか?nextTokenの通常文字をみつけたときは、 Token(OPERATOR,takeFirst)というように、takeFirstの返り値Stringを使っているようだが。
def dump():Unit=reader.first match {
case c:Char if (c==' ' || c== '\t' || c=='\r' || c=='\n')
=> takeFirst ;dump
case _ =>
}
これは、空白を削除する。最初の文字が、空白、タブ、改行等なら、その最初の文字をtakeして、dumpの再帰で、空白等を削除するかチェック(空白等が連続してる場合もあるから)していく。空白等がなくなれば、何もせず、もとにもどるということのようだ。
case class Token(val tokenType:String,val value:String){
override der toString ="["+tokenType+":" "+value+"]"
}
class simpleLexer(input:Stirng){
val OPERATOR="OPERATOR"
val NUMBER="NUMBER"
val EOF="EOF"
var reader =new CarSequenceReader(input)
def netxToken():Token=|
while(!readre.atEnd){
reader.first match {
case c:Char if (c=='+' || c=='-")
=> return new Token(OPERATOR,takeFirst)
case ....................
case c:Char if (c==' ' || c== '\t'...) =>dump
..................
}
.......................
def takeFirst()={
val first =reader.first
reader=reader.drop(1)
first.toString
}
これは、先頭の文字を返すが、その先頭の文字を文字シーケンス(reader)から削除するらしい。
ただ、よくわからないのは、これがdumpの中で使われていて、dumpの返り値はUnitであること。dumpはStringを返すこともあるんだけど、:Unitとすれば、Stringは無視されるんということか?nextTokenの通常文字をみつけたときは、 Token(OPERATOR,takeFirst)というように、takeFirstの返り値Stringを使っているようだが。
def dump():Unit=reader.first match {
case c:Char if (c==' ' || c== '\t' || c=='\r' || c=='\n')
=> takeFirst ;dump
case _ =>
}
これは、空白を削除する。最初の文字が、空白、タブ、改行等なら、その最初の文字をtakeして、dumpの再帰で、空白等を削除するかチェック(空白等が連続してる場合もあるから)していく。空白等がなくなれば、何もせず、もとにもどるということのようだ。
2015年7月26日日曜日
Scalaで学ぶ関数脳入門 Scalaのメールボックス
P280 MailBoxは内部にMessage QueueおよびReceiver Queueを持っていて、send およびreceiveメソッドでメッセージの送受信を行う ことについて説明しているが、けっこうややこしい。
Message Queueとは、send側がメッセージを待機させておくところで、Receiver Queueは、receive側が待ち受け内容を待機させておくところのように見える。両者の準備がととのっていれば、ふたつのqueueの間で、データの受け渡しが行われるというふうに理解したが、、、。
Message Queueとは、send側がメッセージを待機させておくところで、Receiver Queueは、receive側が待ち受け内容を待機させておくところのように見える。両者の準備がととのっていれば、ふたつのqueueの間で、データの受け渡しが行われるというふうに理解したが、、、。
2015年7月20日月曜日
Scalaで学ぶ関数脳入門 変位
P202で、共変、反変の説明をしている。これまでscalaの本やネットの情報を見ても、わかりずらいところだ。
EのサブクラスがEsub、スーパークラスをEsuperとして説明している。
「変数funcは、引数としてEを受け取ることを要求している。一方で、Eは、Esuperの派生型なので、Esuperとしてふるまうことは保証されています。(中略)一方で、EはEsubがどのようにEを拡張しているか知らないため、Esubとしてふるまうことができない。そのため、funcはEsub型を受け取ることができない。」
おもしろい説明の例がありました。こちらです。以下のその抜粋です。参考にさせていただきました。
猫を何かに変換する装置の一種として、動物を変換する装置が含まれるのは自然です。動物を変換する装置で猫を変換できるからです。
また、何かを動物に変換する装置の一種として、何かを人間に変換する装置が含まれるのは自然です。人間も動物の一種だからです。
集合式で書くと
動物 ⊇ 猫 → 動物を何かに変換する装置 ⊆ 猫を何かに変換する装置 (反変性)
人間 ⊆ 動物 → 何かを人間に変換する装置 ⊆ 何かを動物に変換する装置 (共変性)
・動物を何かに変換するのは、猫を変換する装置、犬を変換する装置、、等の共通(AND)集合なので、当然、猫を変換する装置よりも集合としては小さくなるということでしょうか。?
・あるものを人間に変換する装置、あるものを犬に変換する装置、、、等の和(OR)集合が、あるものを動物に変換する装置、、と考えれば、集合の包含関係は上記のようになる?
Wikipediaには、以下の説明がある
T 型の引数を持つ関数呼び出し (fun f (x : T) : Integer と定義) は、T ≤ S のとき、fun g(x: S) : Integer と定義される関数 g で置換可能である。言い換えると、g は、引数の型に関して f より寛容であり、f と同様に Integer を返すので、f をいつでも置換できる。このように、関数引数を許す言語においては、 g ≤ f と f の引数の型とは反変である。
EのサブクラスがEsub、スーパークラスをEsuperとして説明している。
「変数funcは、引数としてEを受け取ることを要求している。一方で、Eは、Esuperの派生型なので、Esuperとしてふるまうことは保証されています。(中略)一方で、EはEsubがどのようにEを拡張しているか知らないため、Esubとしてふるまうことができない。そのため、funcはEsub型を受け取ることができない。」
おもしろい説明の例がありました。こちらです。以下のその抜粋です。参考にさせていただきました。
猫を何かに変換する装置の一種として、動物を変換する装置が含まれるのは自然です。動物を変換する装置で猫を変換できるからです。
また、何かを動物に変換する装置の一種として、何かを人間に変換する装置が含まれるのは自然です。人間も動物の一種だからです。
集合式で書くと
動物 ⊇ 猫 → 動物を何かに変換する装置 ⊆ 猫を何かに変換する装置 (反変性)
人間 ⊆ 動物 → 何かを人間に変換する装置 ⊆ 何かを動物に変換する装置 (共変性)
・動物を何かに変換するのは、猫を変換する装置、犬を変換する装置、、等の共通(AND)集合なので、当然、猫を変換する装置よりも集合としては小さくなるということでしょうか。?
・あるものを人間に変換する装置、あるものを犬に変換する装置、、、等の和(OR)集合が、あるものを動物に変換する装置、、と考えれば、集合の包含関係は上記のようになる?
Wikipediaには、以下の説明がある
T 型の引数を持つ関数呼び出し (fun f (x : T) : Integer と定義) は、T ≤ S のとき、fun g(x: S) : Integer と定義される関数 g で置換可能である。言い換えると、g は、引数の型に関して f より寛容であり、f と同様に Integer を返すので、f をいつでも置換できる。このように、関数引数を許す言語においては、 g ≤ f と f の引数の型とは反変である。
Scalaで学ぶ関数脳入門 抽出子
P183 パターンマッチングと抽出子
class FruitShop {
def niceSale(day:Day){
day match {
case Mysale(salePrice) => printf("Price: %s\n",salePrice)
}
}
}
......
object SaleValidator {
def unapply(day:Day):Boolean~={
day match {
case friday:Friday => true
case monday:Monday => true
case _ => false
}
}
}
object Mysale {
def unapply(day:Day):Option[(Double)]={
day match {
case SaleValidator() => Some(day.salePrice)
case _ => Some(day.price)
}
}
}
抽出子について...apply(ファクトリメソッド)の逆のことを行う。unapplyにより、インスタンスのdayの中の値を取り出すはたらきをする。
val Day(price)=dayで dayからpriceが抽出できる。
SaleValidatorのほうのunapplyはBooleanを返しています。applyが不要な抽出子オブジェクトということで、コップ本の26章の抽出子についての説明にあるようです。
パターンマッチで使うときには、戻り値はOptionかBooleanということらしい。こちらも参照させていただいた。この知識がないと、ここは理解しずらいところかも。。。
class FruitShop {
def niceSale(day:Day){
day match {
case Mysale(salePrice) => printf("Price: %s\n",salePrice)
}
}
}
......
object SaleValidator {
def unapply(day:Day):Boolean~={
day match {
case friday:Friday => true
case monday:Monday => true
case _ => false
}
}
}
object Mysale {
def unapply(day:Day):Option[(Double)]={
day match {
case SaleValidator() => Some(day.salePrice)
case _ => Some(day.price)
}
}
}
抽出子について...apply(ファクトリメソッド)の逆のことを行う。unapplyにより、インスタンスのdayの中の値を取り出すはたらきをする。
val Day(price)=dayで dayからpriceが抽出できる。
SaleValidatorのほうのunapplyはBooleanを返しています。applyが不要な抽出子オブジェクトということで、コップ本の26章の抽出子についての説明にあるようです。
パターンマッチで使うときには、戻り値はOptionかBooleanということらしい。こちらも参照させていただいた。この知識がないと、ここは理解しずらいところかも。。。
Scalaで学ぶ関数脳入門
Scalaで学ぶ関数脳入門を読んでみた。この本も、翻訳本でないので、プログラムの例が理解しやすい。抽象的な内容を理解するには、具体的な例をいろいろ知る必要があるということを、あらためて知らされる。
P180で暗黙の型変換とcaseクラスを組み合わせた、パターンマッチングの紹介があった。
case class Apple(price:Int,num:Int)
case class TotalCalc(price:Int,num:Int){ ①
def totalPrice = price * num
}
implicit def conv(apple:Apple)=TotalCalc(apple.price,apple.num) ②
apple=Apple(100,3)
apple totalPriceで求められる
apple totalPriceのappleは暗黙の型変換でTotalCalcに変換され、その上で、①のtotalPriceを呼び出していることになる。 擬似的に、appleの型をTotalCalcの型に変換し、totalPriceがあたかもappleに定義されているかのように呼び出せる。(ref:scala逆引きレシピ300 P38)
P180で暗黙の型変換とcaseクラスを組み合わせた、パターンマッチングの紹介があった。
case class Apple(price:Int,num:Int)
case class TotalCalc(price:Int,num:Int){ ①
def totalPrice = price * num
}
implicit def conv(apple:Apple)=TotalCalc(apple.price,apple.num) ②
apple=Apple(100,3)
apple totalPriceで求められる
apple totalPriceのappleは暗黙の型変換でTotalCalcに変換され、その上で、①のtotalPriceを呼び出していることになる。 擬似的に、appleの型をTotalCalcの型に変換し、totalPriceがあたかもappleに定義されているかのように呼び出せる。(ref:scala逆引きレシピ300 P38)
2015年7月15日水曜日
scalaファンクショナルデザイン P243
def sum(x: List[Int]):Int={
my.Util.trace("sum",x) {
if(x.tail=-Nil) x.head
else x.head +sum(x.tail)
}
}
..
var level =0
var indicator="_ "
def trace[T](fname:String,arg:Any*)(body:=>T): T= {
println((indicator*lever)+fname+" ("+arg.mkString(",")+")")
level += 1
var ret =body
level -+1
println((indicator*level)+fname+"_ "+ret)
ret
}
...
とあり、最初、(body:=>T)の意味が分からなかったが、要するに、
{ if(x.tail=-Nil) x.head
else x.head +sum(x.tail)
}
の部分に対応するということのようだ。ここで、今の場合はIntの値が計算される。
2015年7月12日日曜日
scalaファンクショナルデザイン P118
クロージャーの利点について書かれてあります。
○コード削減重視バージョン
...............
def output(sw:Int)={
val sum=....
.......
for (.............
for (k<-0 to3){
.......................※計算あり....
if (sw==1) .......
else .................
println(output(1))
println(output(2))........
これだと、その都度、※の部分で同じ計算がされてしまう
○クロージャーバージョン
def output() ={
val sum= ......
.........
for(...........
for (k<-0 to3){
.......................※計算あり....
}
(sw:Int)=> { //クロージャー生成
....
for (k<-0 to 3) {.............
if (sw==1) .......
else .................
val f=opuput()
println(f(1))
println(f(2))
................
※の部分がクロージャーの外側にあるので、最初の1回しか実行されない。
ということのようだ。
いろいろなサイトでも、クロージャーについてわかりやすく書かれているので参考になりました。javascriptやjqueryでも利用されているのだと、今頃になって知りました。
○コード削減重視バージョン
...............
def output(sw:Int)={
val sum=....
.......
for (.............
for (k<-0 to3){
.......................※計算あり....
if (sw==1) .......
else .................
println(output(1))
println(output(2))........
これだと、その都度、※の部分で同じ計算がされてしまう
○クロージャーバージョン
def output() ={
val sum= ......
.........
for(...........
for (k<-0 to3){
.......................※計算あり....
}
(sw:Int)=> { //クロージャー生成
....
for (k<-0 to 3) {.............
if (sw==1) .......
else .................
val f=opuput()
println(f(1))
println(f(2))
................
※の部分がクロージャーの外側にあるので、最初の1回しか実行されない。
ということのようだ。
いろいろなサイトでも、クロージャーについてわかりやすく書かれているので参考になりました。javascriptやjqueryでも利用されているのだと、今頃になって知りました。
2015年7月11日土曜日
Webカメラの活用:離れた場所の様子を見る
狭い場所で行われる内容を、大勢の人が見たいという必要があるとき、別の広い部屋まで映像を配信したいことがあります。それぞれの場所にネットワーク配線がすでにしてあるところであれば、すぐできますが、そうでない場合はなかなか面倒です。
簡単に、なるべくお金をかけずにできないかということで、考えてみました。ビデオカメラからつなぐには、RCAケーブルは30から50mぐらいが限界のようですが、LANケーブルなら100mまでOkです。
Webカメラ、クロスLanケーブル、パソコン2台にフリーソフトでなんとかできるようです。余っていた長いLANケーブルがあったので、クロスでコネクタをつけてみました。
・送信側PCにつなげるWebカメラは、なんでもかまわない。
・パソコンに表示するために、USBCamDispというフリーソフトを送信側のPCで使用する。
・送信側のPCの音声は、録音デバイスのところで、Webカメラ内蔵のマイクの音声をモニター(聴く)できる設定にする。ハウリングしないように、スピーカの音量の調整は必要。
・ネットワークの設定は、2台のPCのIPアドレスを固定にする。ゲートウエイやDNSは、任意でかまわないようです。IPアドレスは、送信側192.168.1.1と受信側192.168.1.2のようにする。
・brynhildrというリモートデスクトップソフトを2台のPCの適当なところに保存しておく。一部、アセンブラ?も使用しているらしく高速です。
最初、送信側をserverモードにして、Ipアドレス192.168.1.1にして、パスワードを設定。ファイヤーウオールは、パブリックネットワークで許可なるようにします。ここに気づかず、最初、苦労しました。セキュリティが心配で、プライベートネットワークで許可としたところだめだったのです。
受信側ではClientモードで192.168.1.1アクセスすれば、うまくつながります。
・受信側PCに大画面液晶TVなり、液晶プロジェクタなりを接続すれば、完成です。
簡単に、なるべくお金をかけずにできないかということで、考えてみました。ビデオカメラからつなぐには、RCAケーブルは30から50mぐらいが限界のようですが、LANケーブルなら100mまでOkです。
Webカメラ、クロスLanケーブル、パソコン2台にフリーソフトでなんとかできるようです。余っていた長いLANケーブルがあったので、クロスでコネクタをつけてみました。
・送信側PCにつなげるWebカメラは、なんでもかまわない。
・パソコンに表示するために、USBCamDispというフリーソフトを送信側のPCで使用する。
・送信側のPCの音声は、録音デバイスのところで、Webカメラ内蔵のマイクの音声をモニター(聴く)できる設定にする。ハウリングしないように、スピーカの音量の調整は必要。
・ネットワークの設定は、2台のPCのIPアドレスを固定にする。ゲートウエイやDNSは、任意でかまわないようです。IPアドレスは、送信側192.168.1.1と受信側192.168.1.2のようにする。
・brynhildrというリモートデスクトップソフトを2台のPCの適当なところに保存しておく。一部、アセンブラ?も使用しているらしく高速です。
最初、送信側をserverモードにして、Ipアドレス192.168.1.1にして、パスワードを設定。ファイヤーウオールは、パブリックネットワークで許可なるようにします。ここに気づかず、最初、苦労しました。セキュリティが心配で、プライベートネットワークで許可としたところだめだったのです。
受信側ではClientモードで192.168.1.1アクセスすれば、うまくつながります。
・受信側PCに大画面液晶TVなり、液晶プロジェクタなりを接続すれば、完成です。
2015年7月9日木曜日
Scalaファンクショナルデザイン P45
Scalaファンクショナルデザインという本が出たので、読み始めてみた。簡潔で読みやすい。
これまで、他のScalaの本で読んで来たことを、振り返って、あいまいだった知識の整理に役立つ。
2行目から
関数オブジェクトは、Function1トレイトやFunction2トレイトをインスタンス化して作られたオブジェクトです。
7行目から
~関数オブジェクトは、変数に格納できるなど、値としての性質を持つことから、クラスでもメソッドでもなく、オブジェクトの一種と考えるのが妥当でしょう。
とある。最初、意味が分かりにくかったが、何回か読み直して、なんとなく理解?した。
関数オブジェクトは、「関数のはたらき」そのものであり、そのはたらきそのものを、変数に格納できるということであり、またそのはたらきを、値とみなすということ。値とみなせるんだから、どちらかといえば、オブジェクト(インスタンス化したもの)だろう。。ということだろうか。
したから7行目より
FuncitonXトレイトにはapplyという抽象メソッドが宣言されており、apply本体が関数本体そのものになります。まず、 関数リテラルが評価されると、FunctionXによるオブジェクトがつくられ、そのときに関数リテラルの「=>」記号の右側がapplyの処理内容として実装されます。以後、関数呼び出しをするとapplyの内容が実行されます。
fun(123)はfun.apply(123)と等価とすることで、fun(123)のように関数呼び出しの形に見えるようにしているということ?と理解したが、いいんだろうか。
P40でapplyの存在理由についてふれている。
fun.apply(123)の例で、ここには関数というものがない。そして、メソッドがないと処理手続きができない。
funは、関数オブジェクトが格納された変数。 実際にはfun関数を呼び出すというのは、格納されているオブジェクトのapplyメソッドを呼び出すことにあたる。
登録:
投稿 (Atom)