プログラミングと日々思ったことなど

ブログ名通りです。仕事でプログラミングをはじめました。

Haskell入門【2+練習問題】

すごいHaskellたのしく学ぼう! | Miran Lipovača, 田中 英行, 村主 崇行 |本 | 通販 | Amazon
これ↑の第8章(p159)から。

複数のI/Oアクションをのりづけして1つにする→do構文 p162

ファイルを開いて追加・観覧・削除 p195

p196 練習問題
ファイルとタスクの番号を受け取り、そのタスクをToDoリストの先頭に持ってくるbump関数を実装する
・unlinesは最後の要素を含め全て末尾に改行文字をつける

bump :: [String] -> IO ()
bump [fileName, numberString] = do
    contents <- readFile fileName
    let todoTasks = lines contents
    let numberedTasks = zipWith (\n line -> show n ++ " - " ++ line)
                                    [0..] todoTasks
    let number = read numberString
    let inTodoItems = todoTasks !! number 
    let newTodoItems = unlines $ delete (todoTasks !! number) todoTasks
    let addTodoItems = inTodoItems ++ "\n" ++ newTodoItems
    bracketOnError (openTempFile "." "temp")
        (\(tempName, tempHandle) -> do
            hClose tempHandle
            removeFile tempName)
        (\(tempName, tempHandle) -> do
            hPutStr tempHandle addTodoItems
            hClose tempHandle
            removeFile "todo.txt"
            renameFile tempName "todo.txt")

これで問題通りには動いた

ランダム性 p199
System.Random モジュールというものがある(先にstackでinstallが必要)
ここのコイントスプログラムを写経していて気づいたのですが、ghcコンパイルする時、プログラム内にmainが無いとエラーになる。ghciだとmainがなくても動く。対話型(式を評価してすぐに結果を得る)ってそういうことなんですね。

bytestring p205
リストの未評価の部分→サンク(thunk)
正格bytestringは遅延性が完全に排除されている。
遅延bytestringは 1 バイトずつ行われるのではなく、64K バイトずつ行われる。この塊をチャンク (chunk) という。

逆ポーランド記法(reverse polish notation)、略してRPN p211
例)10 4 3 + 2 * -
スタック:10 4 3
演算子:4+3 = 7
スタック:10 7(4+3) 2
演算子:7 * 2
スタック:10 14
演算子:10 - 14

答え:-4

対数
対数とは?logって何?対数関数について基礎から解説!|高校生向け受験応援メディア「受験のミカタ」

多相性を実装できる p227
これらの型はどのように振舞うか?と考えて、適切な型クラスに関連付ければ良い。
例)Int は様々な「もの」のように振る舞う。同じかどうか判定できるもの、順序がついたもの、列挙できるもの、etc

IOがファンクターの一種 p229

main = do line <- fmap reverse getLine
                  putStrLn $ "You said " ++ line ++ " backwards!"

ファンクターは aを取ってbを返す関数 と、aの入った箱を渡し、bの入った箱にして返す
Maybeという箱に入っている値に関数を適用できるのと同様に、IOという箱の中に入っている値に関数を適用できるが、fmapした結果もIO。

演算子を作用する対象の中間に記述する関数(*とか)→中置関数

全てのファンクターの性質や挙動は、ある一定の法則に従うことになっている。fmap f をファンクターに適用したら、それはファンクターの中身にfを適用すべきで合って、それ以上のことをしてはいけない。
この挙動はファンクター則に記述されている p234

Applicative p240
型クラスApplicativeは、2つの関数pureと<*>を定義している。
Applicativeは箱の中の関数を適用することができる。
箱で考えるFunctor、ApplicativeそしてMonad - Qiita
ordは文字を取って数値を返す p255

Monoid p257
モノイドは、値を二項演算子で結合できるような型を表す。
data→独自の代数データ型を作る
type→既存の型に型シノニム(既存のデータ型に別名をつける)を与える

newtype→既存の型から新たな型を作る
newtypeは高速。コンストラクタを1つしか作れない。
dataはオリジナルな型を無から作り出す。newtypeは既存の型をもとに、はっきり区別される新しい型を作るもの。

    1. や * の関数を3つ以上の値を1つの値にまとめる計算をする時、値の間に関数を挟む順序を変えても結果は変わらない、という性質がある。 p266

(3 * 2) * (8 * 5)
240
3 * (2 * (8 * 5))
240
この性質を結合的(associativity)と呼ぶ。

リストの連結→concat p269

Foldableは畳み込みできるものを表す。 p277
Preludeのfoldrはリストを取って畳み込みを行う関数で、Data.Foldableのfoldrは、畳み込みできる型ならリストに限らず、何でも受け付ける関数
foldMapがあれば、ある型をFoldableにできる(foldMapさえ定義すれば、その型のfoldrやfoldlは自動的に手に入る

モナドは強化されたアプリカティブファンクター p281
関数 >>= はバインド(bind)と呼ばれる
>>=は、モナド値と普通の値を取る関数を引数に取り、その関数をモナド値に適用してモナド値を得る
do式の中でパターンマッチ が失敗した場合、Monad型クラスのfail関数が使われるので、異常終了という形ではなく、そのモナドの文脈に合った形で失敗を処理できる。p300

>>=は文脈付きの値(モナディックな値)を、「通常の値を取って文脈付きの値を返す関数」に食わせる演算。

MonadPlus→モノイドの性質をあわせ持つモナドを表す型クラス p304
guard→リスト内包表記でフィルタを使うことと同値 p306

p312

(.) :: (b -> c) -> (a -> b) -> (a -> c)
f . g = (\x -> f (g x))

gの型がa -> b で、fの型がb ->c ならば、2つの関数を結合し、gの返り値をfの引数に渡すことで、a -> c 型の新しい関数が作れる。

長くなってきたので切ります。

2のべき乗か判断する公式について【Java】

(n & (n-1))

2のべき乗なのか判断する時に、こんな計算方法がある。
「&」は2進数表示された値にAnd演算を行うもので、And演算を行った時に0となる値が2のべき乗となる。
2進数のAnd演算の方法はこちら
参考↓
kenyu-life.com

結果Javaで書くと

boolean result = ((num & (num - 1)) == 0);

こうなる。

Haskell【Functor型問題と復習】

型宣言
fmap  :: (a -> b) -> Map k a -> Map k b
main :: IO ()
型宣言には定義の型を明示する役割があり、定義が自明である(main :: IO()とか)場合は、これを省略することができる。
定義
main = putStrLn "Hello, Haskell world!"

型クラス
型の振る舞いを定義するもの。
オブジェクト指向におけるクラスとは概念が異なり、Interfaceや抽象クラスに相当。
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not (x /= y)
x /= y = not (x == y)
Eqという名の新しい型クラスの定義。aは型変数で、将来Eqのインスタンスとなるであろう型を表す。

インスタンス
型クラスの制約を満たすように定義した型。
オブジェクト指向におけるインスタンス(クラスの実体)とは概念が異なり、クラスの実装(Implement)に相当。
新しい型クラスを定義するのがclassで、型を型クラスのインスタンスにするのがインスタンス
instance Eq TrafficLight where
Red == Red = True

Functor型クラスの型宣言
class Functor f where
fmap :: (a -> b) -> f a -> f b
Functorの持ってるfmap?
fmapは a -> b を Map k a -> Map k b という関数に変換する関数。

練習問題
Map k がどのようにFunctorのインスタンスになるのか
Map(Data.Map)の関数の型宣言
Map.fromList :: (Ord k) => [(k, v)] -> Map.Map k v
Map.lookup :: (Ord k) => k -> Map.Map k a -> Maybe a
Map.insert :: Ord k => k -> a -> Map.Map k a -> Map.Map k a

有識者の助言

関数(f:: v -> w)を受け取り、任意のMap k v を Map k wに移す関数 fmap を持つ
つまりfmap は全ての値v に対して関数 f を適用し、Mapの値の型を w にするような関数

-- ①
import Data.Map as DataMap
import Data.List as DataList
class MyFunctor f where
	myfmap :: (a -> b) -> f a -> f b
instance (Ord k) => MyFunctor (DataMap.Map k) where
	myfmap f x = DataMap.fromList $ DataList.map (\(p,q) ->(p,f q)) $ DataMap.toList x
-- ②
instance Ord k => Functor (Map k) where
   fmap f = fromList . map (\(k,v) -> (k,f v)) . toList

-- ③
class MyFunctor f where
	myfmap :: (a -> b) -> f a -> f b

instance (Ord k) => MyFunctor (DataMap.Map k) where
	myfmap = DataMap.map

main = return ()

MapはHaskellライブラリですでに定義されている(Mapの実装は隠蔽されている=内部構造ので、値を直接触ることはできない)ため、実際にテストすることはできないらしい。
newtypeを使えばできる(代わりに提供される便利関数を使うと、fmapの実装ができる)と書いてある記事もあるので、読み終わったらもう一度考える。

Haskell入門

Haskellの参考書を読んだので、思い出せるように書いていきます。
すごいHaskellたのしく学ぼう! | Miran Lipovača, 田中 英行, 村主 崇行 |本 | 通販 | Amazon
↑読んだ本

p6の下部にある文章の言い回しが好き

インスタンスとインターフェース p27
インスタンスオブジェクト指向におけるインスタンス(クラスの実体)とは概念が異なり、クラスの実装(Implement)に相当。
ちなみにインタプリタ
人間に分かりやすい高水準プログラミング言語高級言語)で書かれたコンピュータプログラムを、コンピュータが解釈・実行できる形式に変換しながら同時に少しずつ実行していくソフトウェア。英語の原義は「通訳者」。
インタプリタとは - IT用語辞典 e-Words


レンジ・・・範囲のこと

フィボナッチ数列の例から再帰について p51
2つ前の項と1つ前の項を足し合わせていくことでできる数列。
1, 1, 2, 3, 5, 8, 13, 21…

Haskellでは再帰が重要。Haskellでは命令型言語のように計算をどうやってするかを指定するのではなく、求めるものが何であるかを宣言して計算を行う。

最大値を求める例は、リスト内でいくつかのパターンに分解されて、比較をしていました。
基礎的なことですが、面白いですね。
この辺でピボットの意味もわかりました。軸なのですね。

関数は、何か材料を受け取って何かを作り出す小さな工場 p62

コラッツ列 p71

畳み込み p75
畳み込みを使えば、リストを1要素ずつ一回だけ走査してそれに基づいた結果を返すような関数なら何でも実装できる。
畳み込みは2引数関数(2つの引数をとる関数。+やdivなど)と、畳み込みに用いる値(アキュムレータ)の初期値、畳み込むリストを受け取る。

foldrl1のアナロジー(類比) p82

ghci> map ($ 3) [(4+),(10*),(^2),sqrt]
$関数は最も低い優先順位を持つ。右結合なので括弧を消せる
mapは関数とリストを受け取り、その関数をリストの全ての要素に適用
[7.0 , 30.0 , 9.0 , 1.7320508075688772]
(4+3) , (10*3) , (3*3) , (√3)

replicate・・単一の値からなるリストを作る。repeatは1つの要素を受け取り、その要素のみが無限に繰り返される無限リストを生成する。永遠に終わらなくなる。
ghci> replicate 3 10
[10,10,10]

値コンストラクタ関数 p112
値コンストラクタとは、データ型定義の、実際に型が取り得る値の種類を指定する

参考:
【Haskell】 言葉の定義まとめ(型クラス、型コンストラクタ、値コンストラクタ、型引数など) - takafumi blog

エクスポート文の後に括弧をつけないことで、型をエクスポートするけれどもその値コンストラクタは一切エクスポートしない、という選択もできる p116

スカラーとは、ひとつの大きさや量を表す数のこと p125
Eq型クラスは「等値性テストができる物」という振る舞いを定義している。p126

Either a b には値コンストラクタが2つある。Leftを使うと、Eitherの中身はa型になる。Rightを使ったときは、中身はb型になる。Either型を使うと「2つの型のうちどちらか一方」という値を表せる。 p134
data Either a b = Left a | Right b deriving (Eq, Ord, Read, Show)

糖衣構文 (syntax sugar) p136
プログラミング言語で、ある構文を別の記法で記述できるようにしたもの。長い構文を簡略に記述できるようにしたり、複雑な構文を読み書きしやくするために用意される。
[4,5] は構文糖衣を脱がすと 4:(5:[])

結合性(fixity)は優先順位を決めることができる p138
infixr 5 :-: (:-: が新しい関数)
結合性宣言を省略した演算子は全てinfixl 9 になる

instance Eq Maybe where p146
上記のようなインスタンス宣言は不可能。
aには具体型が入るが、Maybeは型引数をを1つ取って具体型を生み出す型コンストラク

Functor型 p151
class Functor f where
fmap :: (a -> b) -> f a -> f b
fmapは、ある型aから別の型bヘの関数と、ある型aに適用されたファンクター値を取り、別の型bの方に適用されたファンクター値を返す関数。

p155 問題:Map k がどのようにFunctorのインスタンスになるのか
この問題については復習がでらまた別記事に。
答えを考える↓
Haskell【Functor型問題と復習】 - プログラミングと日々思ったことなど

PLCプログラミング講座を受けてきました

セミナーの備忘録です。
PLCとは、Programmable Logic Controllerの略で、「入出力を介して各種装置を制御するものであり、プログラマブルな命令を記憶するためのメモリを内蔵した電子装置」と定義されている。

・メーク接点
 何もしない時OFF 操作するとON
・ブレーク接点
 何もしない時ON 操作するとOFF
・非オーバーラップ切替接点
 共通端子(COM)

・リレー 電磁継電器
 コイルと複数の接点で構成され、コイルに電流を流す(励磁)と接点が動作し、コイルに電流を流すのをやめる(消磁)と接点が復帰する。
 考え方としては、電流を流すと磁石になって鉄板が近づく作用を用いてメーク、ブレーク接点が切り替えることになる。という話ですが、PLC内部に多分トランジスタ等があって、それで制御しているのだと思います。

セミナーでは、GX Works2を使用してラダー図を作成しました。
シーケンス制御を表す図には、他にもあります。色々説明してもらいました。
ST言語というのが一番読みやすそうでした。

プログラミングは、タイマ、カウンタと特殊リレーを少し教えてもらいました。
セミナーの最後には、実習もありました。
全問は解けませんでしたが、実習4までは自分で解けました。「X2を押すと、次の運転を開始、3回繰り返して停止する」という問題がわからないまま終わってしまいました。

続けてみたいですが、機材が高すぎますね・・・。
配線はプラスとマイナスを繋げて配線しないと電気が流れないのが、わかっているのですがこんがらがりました。
ラズパイとは違って、ドライバーを使って電線を作ったり、I/O割付表に沿って配線したりなど楽しかったです。

創作人物履歴書ver1.5.1

変更履歴です。

①基本情報の備考欄を空けたファイルが取り込まれない
→取り込まれていなかった(バグ)修正しました。
②年表側と基本情報の名前の統一したい
→データ取込画面にて人物名リストを作成しました。
③エクセル年表の時期未定が取込まれない
→特定の場所の取込が全体的にできていなかった(バグ)修正しました。
④年齢は現状修正できない
→変更可能にしました。
⑤削除・更新画面の作成
→作成しました。
⑥ヘルプ画面に動画
→動画作成してアプリ上から見れるようにしました。
⑦アプリ名表示バグ
→作成しました。
⑧複数回更新すると、チェック画面の表示がおかしくなる問題(テスト中に発見)
→修正しました。