Yuji Yamamoto (山本悠滋)
2017-11-18 DevFest Shikoku 2017
動機:
それだけ!
😂いろいろ乗り越えてさあAndroidからGitHubのAPIを呼ぶぞ!というところで…
... Warning: there were 1 unresolved references to library class members. You probably need to update the library versions. (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember) Warning: Exception while processing task java.io.IOException: Please correct the above warnings first.
_人人人人人人人人人_
> 突然のProguard <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
-dontwarn
や -keep
を重ねてみるも、ゼロにはできず…。-dontwarn
はコピペしたけども。省略します… hask(_ _)eller
… というのは悔しいので、予告通りEtaとHaskellのお話をします!😤
題して!
雰囲気だけは分かる!
Etaを知るためのHaskellの基本!
String
)がキーで整数(Int
)が値の連想配列(Map
)を表す型の場合k
,
v
の代わりにString
とInt
を適用しているclass
というキーワードで始めるが、実際にはインターフェースと似てる
method
という関数が使える型全般をまとめた型クラスSomeTypeClass
の宣言Hoge
という型クラスに属する型」を「Hoge
型クラスのインスタンス」と呼ぶMonad
:
ファーストクラスな「文」っぽいものを表す型をまとめるClass
:
Etaにおいて、「Javaの型をラップした型」をまとめる
+
-
*
/
も!&&
や ||
も!=
とか、::
とか、この後出る
<-
などは組み込み。Javaで言えば…
これも文
複数の「文」がまとまっているのもまた文だったりする
Monad
Monad
を「文」っぽく見せる構文糖:
do
記法do
記法とMonad
do
記法を使った例
do
以降に書いた一行一行がMonad
型クラスの型の値
👇はIO
という最もよく使われるMonad
を使ったdo
do
記法とMonad
do -- <----------------------- do記法の始まり
putStrLn "君の名前は?" -- この行がIO Monad
name <- getLine -- この行もIO Monad
putStrLn "いい名前だね!" -- この行もやっぱりIO Monad
do
ブロックに入るMonad
のインスタンスは、1種類だけ
IO
しか使えない!do
記法とMonad
一般化するとこんな感じ
<-
という記号で代入できるdo
記法とMonad
Monad
を実装した型によって、do
に書いた各「文」と「文」の間でできることが異なる。
do
記法とMonad
つまり、
Monad
を実装した各種型は自由に定義することができるdo
記法とMonad
例えば…
Maybe
Monad
であればで処理が失敗した場合に、do
ブロックの処理を中断することができるMonad
であれば以降の文をリストの各要素に対して実行することができるState
Monad
であればで、do
ブロックの中で暗黙に共有している状態を更新することができるIO
Monad
であればで入出力処理を実行したり、例外を投げたりできる
do
記法とMonad
(再掲)Monad
型クラスに属する型によって、do
記法の中のでできることが違う!
「本物のプログラマはHaskellを使う
- 第22回 FFIを使って他の言語の関数を呼び出す:ITpro」
から拝借した例を一つ。
例えば、C言語のmath.h
で定義されているsin
関数を呼びたいとき。
math.h
で宣言されているCの関数sin
を、Double -> Double
という型の関数c_sin
として呼び出す」という意味。逆にplusOne
というHaskellの関数をC言語で呼び出せるようにしたいとき
例えばGHCで…
MultiWayIf
という言語拡張が使えるようになります。if
/else
がクールに書ける!なんだか闇魔法感がありますが!
Monad
という型クラスで、「文」を一般化している
Monad
に属する型クラスによって、do
の中でできること(=
「文」の意味)を変えることができる繰り返しになりますが…
例: Int
をラップしただけの型SomeType
例: おなじみAndroidのActivity
クラスを使用したいとき
😞Type Familiesとかの説明がだるいのではしょるか…。
import
する引数をとらないメソッドの場合
foreign import ccall "math.h sin" c_sin
などと書いていたとの同じ。
Java Toast ()
とは?Java Toast ()
とは?Java Monad
IO
Monadと違い、型引数を二つとるIO
をはじめMonad型クラスのインスタンスは、すべて型引数を1つとるJava Toast ()
とは?Toast
()
。Javaにおけるvoid
のようなものJava
Monadとは?Monad
という型クラスで、「文」を一般化している
Monad
に属する型クラスによって、do
の中でできること(=
「文」の意味)を変えることができるJava
Monadの場合は?
do
の中でJavaのメソッドが呼べるIO
Monadができること全般import
する->
という記号が関数を表すString
を受け取って(TextView
に対するメソッドが呼べる)Java
Monadを返す」関数となるstatic
メソッドを import
するforeign import java unsafe "@static android.widget.Toast.makeText"
makeText :: Context -> String -> Int -> Java a Toast
a
」は「任意の型」を表す
static
なメソッドはこのように書く。static
メソッドを import
するforeign import java unsafe "@static android.widget.Toast.makeText"
makeText :: Context -> String -> Int -> Java a Toast
ここではJava
Monadの二つ目の引数がToast
であることから分かるとおり、Toast
を戻り値の型として返す
static
メソッドを import
する👇使うときはこう
<-
で代入するJava
Monadを使ってJavaのメソッドを呼ぶ<.>
」を作ったforeign export java "@static info.igreque.keepmecontributinghs.KeepMeContributingWidgetProviderHs.onUpdate"
onWidgetUpdate :: Context -> Java a ()
static
メソッドしかforeign export
できない
foreign export java "@static クラス名.メソッド名"
みたいな形式のみが使えるJava a
なJava
Monadとなる実際に私が実装した関数(一部改変)
Java側ではこう呼ぶ