LoginSignup
0

More than 5 years have passed since last update.

VBAHaskellの紹介 その16(ラムダ式?の生成)

Last updated at Posted at 2015-05-31

(2015/10/1 追記)
以下の記事に書いたlambdaExpr関数は廃止し、代わりにyield式 ( yield_0yield_1 および yield_2 )を追加した。lambdaExpr関数は使うのも説明するのも難しいと思っていたのがその理由だ。
yield_n は関数の評価時にプレースホルダ ph_n (n = 0,1,2)になるもので、下の記事の例でyield式を使うとこう書ける。

'                    ph_1 と ph_2 には評価時に実引数が代入される
'                    yield_1 は評価時に ph_1 になる
f = p_cons(p_makeSole, p_mapF(p_cons(ph_1, yield_1), ph_2))  '[a] : map (a:) b
m = foldr(p_catV, Array(), scanr(f, Array(), a))

f = p_cons(p_makeSole, p_mapF(lambdaExpr(p_cons, 1, ph_1), ph_2))
よりマシになったと思う。


前回記事 VBAHaskellの紹介 その15(引数の部分文字列のリストを取り出す) で、問題を解くためのアドホックな関数を定義して使ったことを不満点としてあげた。

VBAHaskellで実装している関数合成はスコープがフラットで、すべてのプレースホルダに実引数を渡して一斉に評価することしかできないのが問題で、このままでは本物のラムダ式からはほど遠い。

一応これを解決する関数lambdaExprを作ったのでその内容を書く。
Haskell_1_Core モジュールに追加)

問題にしたのは以下のコードだ。

'consMap 関数の定義は cons 関数を map しているだけ
Function consMap(ByRef a As Variant, ByRef v As Variant) As Variant
    consMap = mapF(p_cons(a), v)
End Function
'consMap関数を組み込む
f = p_cons(p_makeSole, p_consMap(ph_1, ph_2))  '[a] : map (a:) b
m = foldr(p_catV, Array(), scanr(f, Array(), a))

ここで p_mapF(p_cons(ph_1), ph_2) というような形に書ければ、consMap関数は不要になる。しかし「すべてのプレースホルダに実引数を渡して一斉に評価することしかできない」と書いたとおり、これに引数 a, v を渡すと mapF(cons(a, a), v) もしくは mapF(cons(a, v), v) などと代入され、先にcons関数が評価されてしまう。本来は mapF(p_cons(a, _), v) というように、引数を代入した後もプレースホルダを残したファンクタのままでいてほしいのだ。
これは要するに引数の代入に対する関数呼び出しを遅延させればいいので、Haskell_1_CoreモジュールlambdaExprという関数を追加してそれができるようにした。

lambdaExprを使うコードはこうなる。1

'                         p_consを第1引数によって遅延 bind1st する
f = p_cons(p_makeSole, p_mapF(lambdaExpr(p_cons, 1, ph_1), ph_2))
m = foldr(p_catV, Array(), scanr(f, Array(), a))

lambdaExprの実質は単なる遅延 bind1st(またはbind2nd) である。
上の p_mapF(lambdaExpr(p_cons, 1, ph_1), ph_2) に引数 a, v を与えると、
mapF(bind1st(p_cons, a), v)
と評価され、最終的に
mapF(p_cons(a, _), v)
という、プレースホルダを残したままの形になっている。
これをラムダ式と呼ぶのは苦しいが lambdaExpr と名付けた。

VBAHaskellの紹介 その15(引数の部分文字列のリストを取り出す)
VBAHaskellの紹介 その1(最初はmapF)


  1. テストモジュール にテスト関数segmentsTest2として追加した。 

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0