ラベル scala の投稿を表示しています。 すべての投稿を表示
ラベル scala の投稿を表示しています。 すべての投稿を表示

2020年11月16日月曜日

実践scala入門を読んでみた

  実践scala入門を読んでみたが、要点がコンパクトにまとまっていて、読みやすい。コップ本も、説明が詳しく深く理解するにはいい部分もあるが、あまりに説明が長く難解なところもある。その点この本は、短期間に概要を理解するにはいい本だと思った。

2020年10月31日土曜日

コップ本(Scala)の読み直し

 数年前読んだ、コップ本を再度読み直してみている。暗黙の変換、暗黙のパラメータのあたりまで読んだところで、暗黙のパラメータがいまいちわかりにくかったので、ネットでもわかりやすい説明ないか探してみる。以下の説明がわかりやすく助かりました。

    https://scala-text.github.io/scala_text/implicit.html

 https://qiita.com/fujisawaryohei/items/c47836beb5ea94e14103

2020年9月18日金曜日

raspi sdカード交換

 やはり、raspiは、サーバーとして利用していると、1,2年程度でSDカードが破損するので、バックアップは必須といえる。システムイメージは、PCに保存し、データはGitでバックアップとるようにしている。
 今回、無料SSL Let's encryptの自動更新の設定をいろいろ試している間に、SDカードの破損が発覚。少し復旧に手間取ってしまったが、なんとか古いバックアップから構築しなおすことができてほっとする。
 壊れてから更新でなく、1年ごと定期的に更新すべきかもしれない。
  raspiはCloud9を入れて使っているが、とても便利である。ただ、使える言語はpython(bottle)等の軽めのものでないと難しいようだ。scala(play)なども考えたけど、やはり難しいようだ。

2018年10月8日月曜日

play scalaをvagrantで動かしてみる(覚書 2018.10現在)

久々にplayを動かしてみると、だいぶ環境が変わっていてとまどった。古いネットの情報では、うまく動かせないようだ。覚書として、手順をまとめてみた。

1 Ubuntuをvagrantで利用してみる
 vagrant init bento/ubuntu-18.04
2 Vagrantfileでいくつか編集
①まず、ポート番号9000が使えるように以下の行を追加
  config.vm.network :forwarded_port, host: 9000, guest: 9000
②メモリを標準の2倍にしてみた。
 config.vm.provider "virtualbox" do |vb|
     vb.memory = "2048"
  end
③ipアドレスを指定してHostOnlyモードを有効にした。
 config.vm.network "private_network", ip: "192.168.33.10"
もし、テスト環境でなく、ネットワーク上の他のPCからアクセスするような
本番環境なら ブリッジモードの必要があり たぶん
config.vm.network "public_network"
とするのかもしれない。

3 仮想OSを立ち上げる
 vagrant up 
4 sshでアクセスする
 vagrant ssh
5  ここから先は以下のリンクがとても参考になりました。sbtのインストールは難しかったのですが、このサイトのおかげで解決しました。
 $ sudo add-apt-repository ppa:webupd8team/java 
 $ sudo apt update
 $ sudo apt install oracle-java8-installer
 $ sudo apt install oracle-java8-set-default
 $ echo "export PATH=/usr/local/anaconda2/bin:$PATH" >> /etc/bash.bashrc
$ echo "export JAVA_HOME=/usr/lib/jvm/java-8-oracle/" >> /etc/bash.bashrc
$ echo "export PATH=$PATH:$JAVA_HOME/bin" >> /etc/bash.bashrc
$ sudo apt-get remove scala-library scala
$ sudo wget www.scala-lang.org/files/archive/scala-2.11.8.deb
$ sudo dpkg -i scala-2.11.8.deb
$ echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823
$ sudo apt-get update
$ sudo apt-get install sbt

6 適当なディレクトリを作りその中でsbt newを行う。sbt new playframework/play-scala-seed.g8

7 ここで、作成されたディレクトリ(上記6で名前を指定できる)に入る(←ここがうっかり逃しやすい!!)
そして、sbtを実行し、runを実行
 しかし、このままでは、外からアクセスできません。
を参考にして
8 ここで、フィルターの設定を変える必要がある。
# conf/application.conf
play.filters.hosts {
    allowed = ["."]
  }
とすればOkである。セキュリティの制限に応じて、この設定は変える必要あると思いますが。

※ネット上のあちこちの情報をかき集めることで なんとか、新しい環境でPlay scalaを動かすことができた。書籍にも、サイトにも、これらのことをまとめてあるところは、まだ少ない?ように思う。




2018年9月30日日曜日

playをscalaで動かしてみる

久しぶりに、playを動かしてみた。以前はactivatorで、動かしていたが、今はダウンロードできないようだ。いろいろ調べてみると、sbtで動かすようになっている。
以下のリンクを参考にしながら、やってみたら、なんとかコンパイルできた。
https://www.supinf.co.jp/tech/2015/06/29/get-started-play2-without-activator/
Webアプリの作成環境は、変化が激しいので、ついていくのが大変なようだ。
Webのフレームワークは、他にもSpringやら、Djangoやら、Railsやら、どれを選ぶか迷いそうだ。

2015年9月13日日曜日

PostgreSqlにslick使用 scala

Herokuにslick利用してみようと試してみているが、けっこう手こずる。activator uiから試してもうまくいかなかったので、以下からgit cloneさせていただいたところローカルやHerokuでうまく動作するところまではこぎつけた。
ローカルでは
psql -U postgres
#create database play_heroku_seed;
で、データベースを作成し
application.confに
 db.default.user=ユーザー名
 db.default.password="パスワード"
とすればOKだった。
Herokuにはすにで、postgrsqlが動いているので
heroku login
heroku create
git add .
git push heroku master
heroku open
******************************************
ユーザー名とパスワードを設定すると、ローカルではいいが、Herokuではやはり
だめだったので、ローカルでも環境変数DATABASE_URLを変更してみたらOkだった。
postgres://[username]:[password]@[host]:[port]/[database]

2015年8月17日月曜日

slickの設定

ネット上の情報をもとに、slickの設定しようとしたが、うまくいかない。どうやら、バージョンをplayに合わせる必要があるようだ。最新版のバージョンを調べて、設定してみたら、なんとかなった。
以下build.sbtの中身
libraryDependencies ++= Seq(
  jdbc,
  cache,
  ws,
  specs2 % Test,
   "com.typesafe.slick" %% "slick" % "3.0.2",
  "org.slf4j" % "slf4j-nop" % "1.6.4",      
  "com.typesafe.play" %% "play-slick" % "1.0.1"
)
このあと
activator update
activator eclipse
を実行することで、eclipseでの編集ができるようになるようだ
*************
このあと、ネットを参考に、サンプルプログラムを試してみるが、うまくコンパイルできない。
import play.api.db.slick.Config.driver.simple._と
あるけれど、実際には
  import slick.driver.H2Driver.api._
  import slick.lifted._
 などが必要?でも、slickのバージョンが少し違うといろいろなところで、はじかれてしまう?依存関係がいまいちよくわからない。まだまだ実用的なソフトをscalaでつくるには壁がありそうだ。


2015年8月15日土曜日

scala playをeclipseで使ってみる

scalaでplayを利用してみた。コマンドラインからは、ネットの情報でなんとか使えるようになったが、eclipseの設定については、試行錯誤が必要なようだ。
とりあえず、以下のリンクを参考にさせていただいた。
http://qiita.com/Orfeus/items/84635a5ff86ba093f408

・java、javac、activatorのフォルダのパスは通しておいた。playのminimum版を解凍。
・やはりaddSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0")をplugin.sbtの中に追加しないとだめだった。
・activator newで6)play-scalaを選択  適当な名前(今回はtest)をつける cd test
でactivator runで 実行できることを確認する。
・activator compileを行ってから、activator eclipseでプロジェクトファイル作成ができるようだ。そしてeclipseでimport と、ここまでは前回の復習。

・緑に白抜き三角と鞄のアイコンのわきの▼をクリック>外部ツールの構成で、プログラムを右クリック>新規>ロケーションで、activator.batを選択、作業ディレクトリは、同じフォルダ指定、引数にrunとしてみたら、いちおう動いたようだ。
が、止め方がまだよくわからない。コマンドプロンプトであれば、CTRL+Dで止めるのだが、、、。
 ソースを修正して、再コンパイルするとエラーとなる。ただ、再表示させると、自動的にリロードしてくれるので、修正は反映されるようだが。。。

2015年7月30日木曜日

play2+scala

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月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(...
 ....
ここでは、再帰は見当たらない?一桁数字+一桁数字の単純な式だけの処理をしているということだろうか?
このへんになってくると、パーサーの複雑さを感じる。

*********
いちおう、最後まで全ページを読んでみた。全体的に、関数型に関する記述は少ないので、関数型プログラミングの学習にはあまりならなかったが、基本的な並列処理やパーサの記述がとても参考になった。

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の再帰で、空白等を削除するかチェック(空白等が連続してる場合もあるから)していく。空白等がなくなれば、何もせず、もとにもどるということのようだ。


2015年7月26日日曜日

Scalaで学ぶ関数脳入門 Scalaのメールボックス

P280 MailBoxは内部にMessage QueueおよびReceiver Queueを持っていて、send およびreceiveメソッドでメッセージの送受信を行う ことについて説明しているが、けっこうややこしい。
 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 の引数の型とは反変である。

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ということらしい。こちらも参照させていただいた。この知識がないと、ここは理解しずらいところかも。。。


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)



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でも利用されているのだと、今頃になって知りました。

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メソッドを呼び出すことにあたる。

2015年6月30日火曜日

scala関数型デザイン&プログラミング P243

モノイド、モナドの章は、抽象的な内容で難しいといえば難しいのだが、試行錯誤の文章が少ないので、パートⅡの章に比べれば読みやすい。途中の問題への取り組みはあちこち省き、読み進んだ。

結合律の説明がすぐには理解できなかったので、丁寧にたどってみた。
x.flatMap(f).flatMap(g)==x.flatMap(a=>f(a).flatMap(g))の結合律で、xをSome(v)に置き換えると
Some(v).flatMap(f).flatMap(g) == Some(v).flatMap(a=>f(a).flatMap(g))であることを示す。
def flatMap[B](f:A=>Option[B]):Option[B]だから、
左辺のSome(v).flatMap(f)の部分はSome(v)のvに関数fを適用してf(v):Option[B]となる。
右辺のほうは、Some(v)のvに関数a=>f(a).flatMap(g)を適用するので、
v=>f(v).flatMap(g)で、結局f(v).flatMap(g)

Exercise11.7 クライスリ関数composeを実装せよ
def compose[A,B,C](f: A => F[B], g: B => F[C]): A => F[C] =
  a => flatMap(f(a))(g)
f: A => F[B]の部分は、a=>f(a)で、次にg: B => F[C]のところは、flatMapを使うしかない。
( def flatMap(g:B=>F[C]):F[C]とみなして )
f(a).flatMap(g)とも書けるが、flatMap(f(a))(g)ということ。

Exercise 11.9 flatMapの観点からの結合律と、composeの観点からの結合律の式が等価であることを証明せよ。
compose(compose(f, g), h) == compose(f, compose(g, h))

a => flatMap(compose(f, g)(a))(h) == a => flatMap(f(a))(compose(g, h))
a => flatMap((b => flatMap(f(b))(g))(a))(h) == a => flatMap(f(a))(b => flatMap(g(b))(h))
左辺を少し簡単にすると
( b => flatMap(f(b))(g) )(a)は b => flatMap(f(b))(g)にaを適用するということ
だから a=> flatMap(f(a))(g) つまり下記のようになる
a => flatMap(flatMap(f(a))(g))(h) == a => flatMap(f(a))(b => flatMap(g(b))(h))
aを除いて簡単にする。f(a)の代わりにxとすると
flatMap(flatMap(x)(g))(h) == flatMap(x)(b => flatMap(g(b))(h))
文字を置き換えると
flatMap(flatMap(x)(f))(g) == flatMap(x)(a => flatMap(f(a))(g))
ん~ けっこう、ややこしい。

2015年6月27日土曜日

scala関数型デザイン&プログラミング P195

Exercise 9.7 flatMapをベースとしてproductとmap2を実装せよ
def product[A,B](p: Parser[A], p2: => Parser[B]): Parser[(A,B)] =
  flatMap(p)(a => map(p2)(b => (a,b)))
def map2[A,B,C](p: Parser[A], p2: => Parser[B])(f: (A,B) => C): Parser[C] =
  for { a <- p; b <- p2 } yield f(a,b)
 for内包表記は、もう忘れていた
P74を参考にすれば
 p flatMap ( a =>
  p2 map ( b =>
   f(a,b))) という意味になる
Exercise 9.8 mapをflatMapや他のコンビネータをベースにして表現せよ
def map[A,B](p: Parser[A])(f: A => B): Parser[B] =
 p.flatMap(a => succeed(f(a)))