ようやく前に進めました

入門Haskellプログラミングを読みながら Haskellの勉強を未だに続けています 何回も何回も挫折の連続ですが、ようやくサンプル・プログラムが作動しました

 

— $stack ghci addressLetter.hs で読み込む
— そして以下のようにこの関数を呼び出すと出力が適切に変化する
— *Main> addressLetter (“Bob”, “Jones”) “sf”
— “Bob Jones – PO Box 1234 – San Francisco, CA, 94111”
— *Main> addressLetter (“Bob”, “Jones”) “ny”
— “Bob Jones : PO Box 789 – New York, NY, 10013”

  

addressLetter name location = locationFunction name
  where locationFunction = getLocationFunction location

  

sfOffice name = if lastName < “L”
                then nameText
                  ++ ” – PO Box 1234 – San Francisco, CA, 94111″
                else nameText
                  ++ ” – PO Box 1010 – San Francisco, CA, 94109″
  where lastName = snd name
        nameText = (fst name) ++ ” ” ++ lastName

  

nyOffice name = nameText ++ ” : PO Box 789 – New York, NY, 10013″
  where nameText = (fst name) ++ ” ” ++ (snd name)
renoOffice name = nameText ++ ” – PO Box 456 – Reno, NV 89523″
  where nameText = snd name

  

getLocationFunction location = case location of
                               “ny” -> nyOffice
                               “sf” -> sfOffice
                               “reno” -> renoOffice
                               _ -> (\name -> (fst name) ++ ” ” ++ (snd name))
  

このようなプログラムです 本からコピーしましたが、HaskellではPythonのようにインデントにも論理的に重要な意味があり、それを間違えると作動しませんし、compileもできません 何回はねられましたが最後に動作しました 出力例もコメントに記載しています

だいぶん頭脳が Haskell脳になってきました

最近感じるのですが、これまでの半年間以上に渡る苦闘の末に、いやまだまだ末ではないのですが、自分の思考がなんだか変わりつつあるのを自覚するようになってきました。要するに Haskell脳になってきているのです。もっともその道のプロの方から見れば「赤ちゃん」のように幼稚な脳でしょうが、それでも変わりつつあります。

そのように自覚するのは、別に Haskellの勉強をしたり、プログラムを書いたりしている時ではないのです。日常生活で、フト今までとは違った思考をしているのに気づくのです。ようやくここまで来ました

-- Haskellで書いた
--リストより先頭文字が一致した項目
--を削除するプログラム
-- remove0.hs

remove' hanbetsu [] = []
remove' hanbetsu (x:xs) = if hanbetsu x
                          then remove' hanbetsu xs
                          else x:remove' hanbetsu xs

test_array = ["apple", "banana", "avogado"]

このソースコードは remove0.hsとしてセーブされています。
これでターミナルから以下のように打ち込みます

$stack ghci

これによりHaskell Interpreterが立ち上がりますので以下のようにプログラムのソースコードである remove0.hs

Prelude>:l remove0.hs

とすることによりコンパイルされますそして

Main>remove' (\(x:xs) -> x == 'b') test_array

とすることにより”banana”のみ無くしたリストが得られます。

Haskellに惑わされ – 13

ライブデモンストレーション開始の直前に理解を深めるために ghciで REPLにより実行しました

Prelude> :{
Prelude| myDiv x = case x of (0, 0) -> 1 :: Int
Prelude|                     (_, 0) -> maxBound
Prelude|                     (n, m) -> n `div` m
Prelude| :}
Prelude> myDiv (0, 0)
1
Prelude> myDiv (100, 0)
9223372036854775807
Prelude> myDiv (3, 5)
0
Prelude> myDiv (100, 2)
50

思いどおりの実行ができましたね もっとも本からの抜粋ですが・・・・ しかし、本に書いているからと言っても簡単に実行できないのが Haskellです 要するにとても「厳しい」言語仕様なのです

Haskellに惑わされ – 12

この本「ふつうのHaskellプログラミング」といのはとても良い本のような気がしてきました。というのも僕のHaskell programmingに対する理解が前に進んでいるからです。「前に」という修飾語に注目して下さい。決して「理解が進んでいる」とは言っていません。しかし、着実に前に進んでいます。

本日確実にゲットした理解は、

$stack runghc

というコマンドです。これを行うことにより、実行ファイルが作成されます。それは、Macだろうが Windows10だろうが、Linuxだろうが同じです。そしてできるファイルは、拡張子無しの実行ファイルなのです。

例えば expand.hsというソースコードファイルがあれば、それをこのコマンドでコンパイルすれば、expandという名前の実行ファイルができあがります。ですから、実行するには

$./expand

とすれば良いのです。これだけ理解するにも時間が必要であり、着実な前に向かった進歩です。大分Haskellの世界観に馴染んできました。僕という人格、いや人格でなく能力が拡大しているのです。

Haskellに惑わされ – 11: 鎌倉ライブデモンストレーションHome Page改修作業に着手

何時の間にか 8月も真ん中になってしまいました これまでのんびりと構えていたのですが、そろそろ鎌倉ライブデモンストレーションHome Page (https://www.kamakuralive.net/)の改修作業に着手せねばなりません。

ただ改修するのも進歩が無く面白くありませんので、今年は Bootstrap > 4.0で組み直すつもりです。もちろん jQueryも version upですね。本日ようやく着手しましたが、web programmingは久しぶりなので色々なことを忘れてしまい出発点まで自分を戻すのが大変です。

では何をこれまでその代わりにしていたかって? 例によって Haskellです こんな良い本を見つけたのですが、読んで行くにつれ難解になります。どうしてこの computer languageはこんなにも難しいのでしょうか?

この本は10年以上前に出版され、現在は入手できませんので、中古品を購入するしかありません。幸い、とても安価でしたので助かります。内容は不親切ながらも良く書けていると思います。しかし難しい

ふつうのHaskellブログラミング
ふつうのHaskellブログラミング

Haskellに惑わされ – 10

この3日間 Haskellに格闘です 格闘といっても、巨大な怪獣に武器も無く立ち向かうが如くであり、もともと勝つことは不可能な戦いです

こんな時にはどうするか? 問題を切り分けるしかありません そもそも \関数 (ラムダ関数)をおまえさんは使えるようになったのですか?

うーん 自信無いなあ

それでは

たとえば 100::Intから 120::Intまでの整数リストがあった時、これを全て 3倍にするには どうするか? うーんこの前学んだ map関数を使用すれば簡単!

Prelude>map (*) 3 [100 .. 120]

ああ ダメダメこれでは動作しません Haskellより怒られます 何故かと言えば mapは

Prelude> :t map
map :: (a -> b) -> [a] -> [b]

で分かるように、 2引数関数なのですよね ところが、Prelude>map (*) 3 [100 .. 120]などとすれば 3引数となってしまいますよね

ではどうするか? もちろん mapが適用するのは、関数なのであり、(*) 3 などというのは関数ではありません 関数にするには (3 *)とすれば良いはずです そうすると きたきたーっ

Prelude> map (3 * ) [100 .. 120]
[300,303,306,309,312,315,318,321,324,327,330,333,336,339,342,345,348,351,354,357,360]

はいできましたねっ ばっちりです

Haskellに惑わされ – 9

もうむちゃくちゃ Haskellの難しい世界に完全にやられています 何が何だかさっぱり分からない それでも頑張って前に進むのだ きっとこの森を超えればこれまで見たことも無い世界が広がっているのだ それを信じて進むしかない

ところで、例の’\’というのは要するにギリシャ語の ‘λ’という文字に似ていますね、それでこの記法を「ラムダ式」と呼ぶのです 正確には「ラムダ関数」でしょうか 関数というのはある入力 aが入れば、何らかの操作をその aに対して行い、結果 bを返すものですね この時重要な概念としては、この関数 (ここでは便宜上 f と呼びます) f に aという入力をすれば、必ず bというものが返る、という点です

ただ、名前 f というのは本質的で無いので、ここは何でも良い、そんな意味で \ というものを使用するのです つまりこの関数が行う操作そのものが重要で名前はどうでも良いのです これを ラムダ関数と呼びます

Haskellに惑わされ – 8

それでは自己設問の3に移ります ここはMac日本語キーボードに限定します さて “\” という斜め棒はどうすれば打ち込めることができるでしょうか?
これって悩みますよね
実は Macの場合 Option Keyを押しながら ¥キーを打つと この斜め棒になります

やってみてくださいね

Haskellに惑わされ – 7

これで先の自己質問1に対する回答となりましたね、シングルクォーテーション `はプログラム上何の意味も無いものであり、従って名前の一部にもならないのですね

だから Haskellでも add’という名前は許されても、add`という名前は許されません もちろん、ここで addと add’とは別物とみなされますので、この性質は もともとある名前と似た作用を有する名前を命名する時に便利です

たとえば、Haskellの Prelude frameworkにはもともと addという関数が定義されているので、自分で新たに add = 加える という意味を有する関数を作成したとしても、addという名前を使用できません

こんな時に add’とすれば別物とみなされ自分で新たに定義した関数をadd’という名前で使えるのですね

こんなことを理解するにも数日間頭を悩まされました バカみたいなことだけど、きっと世の中には僕と同じような悩みを抱えて Haskell programmingから挫折した人は何人もいるのだろうと思います

まあこれで

Haskellに惑わされ – 5

の自己設問1と2は解決ですね

Haskellに惑わされ – 6

例えばこうです 僕が良く Web programmingする時に使用する PHP言語ですが、database言語であるSQL (僕が使用しているのは open sourceの MySQL言語です)と連携してSQLサーバーよりデータを取得し、それをサーバー内で PHP言語により加工し、その結果を http通信でクライアント側 つまり、一般ユーザーに送っているのですが、その部分の肝腎の SQL serverからの PHPでのデータ取得部分の一例はこんなものです

$row_session = $stmt_session->fetch( PDO::FETCH_ASSOC );
$stmt_role = $pdo->prepare( "SELECT MAX(`created`) FROM `role_tbls`;" );
$stmt_role->execute();

ここで出てきましたよね この部分です

"SELECT MAX(`created`) FROM `role_tbls`;"

この部分を良く見ると、

`created` や`role_tbls`

のように何だかさっきのもの (`)ではさまれていますね これは実は SQL構文規則では不要なものです しかしながら、この列が SQLの列名であることを分かりやすくするためにわざわざ用いているのです

つまり、 (`)というものはプログラム解析上では何の意味も持たない飾りだということです

従ってこの部分に(‘)というものを使用すると途端に文法エラーとなりプログラムは走りません これと同様のことが Haskellでも起こるのです