状態モナドを作ってみる
typescriptで状態モナドを作ってみます。
状態モナドは
という状態を受け取って結果と変化した状態を返す関数です。
これを
export type State<R,S> = (s:S) => {result:R,state:S}
と定義しておきます。
初期値を作る関数を
export const unit = <R,S>(result:R) => (state:S) => { return {result:result, state:state}};
と定義します。これで
const m0 = unit<number,number>(100);
のように初期入力値を作ることができます。
次に数を2倍する関数を作りましょう。そして関数が呼ばれる回数を状態としてカウントすることを考えます。
具体的には
const f = (r:number) => (s:number) => { return {result:r*2, state:s+1}}
のような関数を用意します。つまり、状態を受け取ったら値を2倍しつつ状態を更新して返すという関数です。
これは
const f: (number) =>State<number, number>
という型を持っていることに注意しましょう。
作っておいた状態モナドm0にこの関数を適用するための関数としてbindを用意します。
export const bind = <R,S,Q>(m:State<R,S>, f:(r:R)=>State<Q,S>) => (s:S) => { const next = m(s); return f(next.result)(next.state); }
これは新しく状態モナドを作って、その状態モナドでは、元の状態モナドを先に使って結果を求め、それにfを適用するようにしてあります。
bindを使って、m0にfを3回くらい適用させてみましょう。
const m0 = unit<number,number>(100); const m1 = bind(m0,f); const m2 = bind(m1,f); const m3 = bind(m2,f);
m1,m2を用いたのはわかりやすさのためで、bindを連続して作用させても構いません。
できた結果の状態モナドm3を使うには初期状態を設定する必要があります。
const ans = m3(0)
ans.result == 800
ans.state == 3
となり、きちんとカウントしていることがわかると思います。
状態モナドの説明はこれで終わりです。
色々な使い方がありそうだということがわかると思います。
以上をまとめたコードがこちらになります。
export type State<R,S> = (s:S) => {result:R,state:S} export const unit = <R,S>(result:R) => (state:S) => { return {result:result, state:state}}; export const bind = <R,S,Q>(m:State<R,S>, f:(r:R)=>State<Q,S>) => (s:S) => { const next = m(s); return f(next.result)(next.state); } export function stateTest() { /// double number , state: count of operation const f = (r:number) => (s:number) => { return {result:r*2, state:s+1}} const m0 = unit<number,number>(100); const m1 = bind(m0,f); const m2 = bind(m1,f); const m3 = bind(m2,f); const display = <R>(m:State<R,number>) => { console.log("result:"+m(0).result + " state:"+m(0).state); } display(m0); display(m1); display(m2); display(m3); /* result:100 state:0 result:200 state:1 result:400 state:2 result:800 state:3 */ } stateTest();
ありがとうございました。
htmlのタグをつける
for i in range(1,200): display = "" if i==1 or i>99: display=" style=\"display:none;\"" print("<option data-value=\""+str(i) + "\""+ display + ">"+str(i)+"回</option>")
checkのあるなし
let checked = ($("[data-hoge]").is(":checked")) ? true : false;
チェックを付けたい場合
$("[data-btn-hoge] input").prop("checked",true);
console.logの置き換え
console.log\((.*)\)
で
debuglog($1)
iosのwkWebViewでズームさせない
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0,muser-scalable=no">
ローカルHTMLのメモ
WKWebViewで実装すると
フォルダ参照ならhtml内のlinkは./でプロジェクト直下になっているようだ。
WKWebViewは今の所、コード上で貼り付けるしかない。
WKNavigationDelegateでnavigationResponseでdocument.locationの移動を検知できる。
decisionHandler(.allow)で許可する。
challenge: URLAuthenticationChallengeで
信頼するかどうか
print("[Warning]challenge AuthenticationChallange") let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!); completionHandler(.useCredential, cred)
Build Phaseでプロジェクト直下のファイルをResourceにコピーできる。
ResourceにコピーできればMainBundleから取得できる。
ビルド設定表示
プロジェクトファイルのある階層で
xcodebuild -showBuildSettings
cmakeの仕方
以下を参考にする。
qiita.com
コマンドラインのビルド
main.cpp, hello.hppがあるとする。
これらをまず
g++ -c main.cpp hello.hpp
とコンパイルして.oファイルを作る。
そしてリンクする。
g++ -o a.out main.o hello.o
cmake
CMakeLists.txtを作る
cmake_minimum_required(VERSION 2.8) project(sample_project CXX) add_executable(a.out main.cpp hello.cpp)
buildフォルダを作り、そこで実行する。
mkdir build cd build cmake .. make