Haskellのドット演算子(.)
f . g
と書いたときにg
の結果がfに渡されるイメージで、Unix
の|
パイプに例えられます。
*> :t (.) (.) :: (b -> c) -> (a -> b) -> a -> c
表現は正確ではありませんが、渡される結果が「1つ」でなくても、ドット演算子は使えます。
> let f = undefined :: b->c->d > :t f f :: b -> c -> d > let g = undefined :: a->b->c > :t g g :: a -> b -> c > :t f . g f . g :: a -> c >
b->c
を(b->c)
をみなして、
f :: b->c->d ------> (b->c)->d g :: a->b->c ------> a->(b->c)
と考えます。
CPUの作り方
- 作者: 渡波郁
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2003/10/01
- メディア: 単行本(ソフトカバー)
- 購入: 35人 クリック: 445回
- この商品を含むブログ (193件) を見る
読者が具体的なイメージを持って理解出来るように、文章が工夫されている。
準備は必要最低限に絞っている。
- ともかくその時点の知識で、まずは1bit CPUを作ってみる。
前半の方は、必要最小限のアナログの説明もされている。
6章からがCPUの説明
プルアップ(プルダウン)->CRフィルタ->チャタリング防止->シュミットトリガ->リセット回路の説明の流れが秀逸
- ただし、シュミットトリガの説明は天下り
ROMを自作するので、ROMの基本的な構造が具体的にわかる。
- ROMプログラムを格納する場所という(完全に間違いではないが)杓子定規に解釈すると誤解を招く表現の正しい解釈の説明がある。
P.132-P.134の配線パターンの部分はよくわからなかった。実際に自作するときは苦労しそう。
前提知識
数値の大小関係の判断 -> キャリーの有無で判断
ドライブ能力の説明あり
引用
- 転送の途中に演算回路があれば演算命令に化けるだけ (p.171)
GhcLintでコードをチェックする
結果集計
$ grep "^src" doc/wk_lint_result.md | cut -d " " -f 4- | sort | uniq -c | sort -r 18 error| Suggestion: Move brackets to avoid $ 8 error| Suggestion: Redundant $ 7 error| Suggestion: Redundant bracket 4 error| Suggestion: Avoid lambda 3 warning| Redundant return 3 warning| Redundant lambda 3 error| Suggestion: Use String 2 error| Suggestion: Use infix 1 warning| Use notElem 1 warning| Redundant if 1 warning| Redundant do 1 warning| Evaluate 1 warning| Eta reduce 1 error| Suggestion: Use if
$
の無駄使いが多いようです。
また、全体的にRedundant
が多いですね。割合を計算してみると。
$ grep "^src" doc/wk_lint_result.md | cut -d " " -f 4- | sort | uniq -c | sort -nr | awk '{a += $1;} END {print a}' 54 $ grep "^src" doc/wk_lint_result.md | cut -d " " -f 4- | sort | uniq -c | sort -nr | grep Redundant 8 error| Suggestion: Redundant $ 7 error| Suggestion: Redundant bracket 3 warning| Redundant return 3 warning| Redundant lambda 1 warning| Redundant if 1 warning| Redundant do $ grep "^src" doc/wk_lint_result.md | cut -d " " -f 4- | sort | uniq -c | sort -nr | grep Redundant | awk '{a += $1;} END {print a}' 23 $ echo "23/54*100" | bc -l 42.59259259259259259200
42%が冗長でした。
結果内容
- 冗長なラムダ
src/Atoparsec05.hs|72 col 1 warning| Redundant lambda || Found: || incAndaddBindParserState || = \ bind ParserState{..} -> || ParserState (markerIdx + 1) (bind : bindList) || Why not: || incAndaddBindParserState bind ParserState{..} || = ParserState (markerIdx + 1) (bind : bindList)
- エータ簡約する
src/Atoparsec05.hs|110 col 5 warning| Eta reduce || Found: || mkBin ope x y = mkBinaryOperator (BC.unpack ope) x y || Why not: || mkBin ope = mkBinaryOperator (BC.unpack ope)
- [Char]ではなくStringを使う
src/Atoparsec05.hs|117 col 11 error| Suggestion: Use String || Found: || [Char] -> Parser Char || Why not: || String -> Parser Char
- ライブラリにある関数を使う
src/Atoparsec05.hs|118 col 28 warning| Use notElem || Found: || not (elem c xs) || Why not: || notElem c xs
notElem
なんてあったかなとおもったら、確かにある。
*Atoparsec04> :t elem elem :: (Foldable t, Eq a) => a -> t a -> Bool *Atoparsec04> :t notElem notElem :: (Foldable t, Eq a) => a -> t a -> Bool
- 中置演算子を使う
src/Atoparsec05.hs|118 col 33 error| Suggestion: Use infix || Found: || elem c xs || Why not: || c `elem` xs
- タプルから値を取り出して関数適用するのではなく、関数をuncurryして直接タプルを関数適用できるようにする。
src/Atoparsec05.hs|268 col 28 warning| Evaluate || Found: || ope_ lhs (fst $ P.head xs) (snd $ P.head xs) || Why not: || uncurry (ope_ lhs) (P.head xs)
- do不要
src/Atoparsec05.hs|331 col 22 warning| Redundant do || Found: || do case val of || Left sch -> do lift $ char '.' || x <- _idenStr || params <- parenExprList || return $ expr $ mkFunctionCall' x sch params || Right idn -> do params <- parenExprList || return $ expr $ mkFunctionCall' idn "" params || Why not: || case val of || Left sch -> do lift $ char '.' || x <- _idenStr || params <- parenExprList || return $ expr $ mkFunctionCall' x sch params || Right idn -> do params <- parenExprList || return $ expr $ mkFunctionCall' idn "" params
- 評価結果を返すならif不要
src/Atoparsec05.hs|415 col 11 warning| Redundant if || Found: || if x == '+' then True else False || Why not: || x == '+'
- 不要なかっこ
src/Atoparsec05.hs|477 col 14 error| Suggestion: Redundant bracket || Found: || (lift $ string "json") <|> || (lift (string "datetime" <|> "date" <|> "time")) || Why not: || (lift $ string "json") <|> || lift (string "datetime" <|> "date" <|> "time")
- 不要なラムダ
src/Atoparsec05.hs|570 col 37 error| Suggestion: Avoid lambda || Found: || \ x -> x == c || Why not: || (== c)
- 不要な$
src/Atoparsec05.hs|588 col 8 error| Suggestion: Redundant $ || Found: || lift $ peekChar || Why not: || lift peekChar
- caseで評価をTrue/Falseでする場合ifをつかう
src/Atoparsec05.hs|594 col 8 error| Suggestion: Use if || Found: || case arw of || True -> do docPathArrow || docPath <- (lift $ char '$') >> (lift $ char '.') >> || atomDocumentPath || return $ || exprColumnIdentifier $ || columnIdentifierNameDocumentPahtItem str docPath || False -> return $ exprIdentifierName str || Why not: || if arw then || (do docPathArrow || docPath <- (lift $ char '$') >> (lift $ char '.') >> || atomDocumentPath || return $ || exprColumnIdentifier $ || columnIdentifierNameDocumentPahtItem str docPath) || else return $ exprIdentifierName str
- 不要なリターンは避ける。(多分コードを書いていて途中に検証用のロジックをいれいて消したのでこの形になっていたのだと思う。)
src/Atoparsec05.hs|666 col 20 warning| Redundant return || Found: || do x <- many1 atomPathItem || return x || Why not: || do many1 atomPathItem
- かっこの範囲は必要最低限に狭くする
src/Atoparsec05.hs|709 col 20 error| Suggestion: Move brackets to avoid $ || Found: || (lift $ string "[*]") >> return '*' || Why not: || lift (string "[*]") >> return '*'
- 不要なラムダは避ける
src/Atoparsec05.hs|712 col 20 error| Suggestion: Avoid lambda || Found: || \ x -> (mkArrayIndex . fromIntegral) x || Why not: || (mkArrayIndex . fromIntegral)
- $を避ける
src/Atoparsec05.hs|725 col 18 error| Suggestion: Move brackets to avoid $ || Found: || (lift $ stringCI "asc") <|> lift (stringCI "desc") || Why not: || lift (stringCI "asc") <|> lift (stringCI "desc")
Haskellのエスケープ(\)の挙動
function \ string | "a" | "\a" | "\\a" | "\\\a" |
---|---|---|---|---|
repl | "a" | "\a" | "\\a" | "\\\a" |
length | 1 | 1 | 2 | 2 |
mapM_ print | 'a' | '\a' | '\\' 'a' |
'\\' '\a' |
show | "\"a\"" | "\"\\a\"" | "\"\\\\a\"" | "\"\\\\\\a\"" |
mysqlshでのアクセス
すぐ忘れるのでメモ
$ mysqlsh -u root -P 8000 Creating a Session to 'root@localhost:8000' Enter password: Node Session successfully established. No default schema selected. Welcome to MySQL Shell 1.0.9 Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type '\help', '\h' or '\?' for help, type '\quit' or '\q' to exit. mysql-js> session <NodeSession:root@localhost:8000> mysql-js> \sql Switching to SQL mode... Commands end with ; mysql-sql> show schemas; +--------------------+ | Database | +--------------------+ | information_schema | | performance_schema | | world_x | | x_protocol_test | +--------------------+ 13 rows in set (0.02 sec) mysql-sql> use x_protocol_test; Query OK, 0 rows affected (0.01 sec) mysql-sql> show tables; +---------------------------+ | Tables_in_x_protocol_test | +---------------------------+ | alltypes | | bar | | bazz | | data_type_date | | data_type_datetime | | data_type_decimal | | data_type_decimal1 | | data_type_decimal2 | | data_type_enum | | data_type_time | | data_type_timestamp | | data_type_year | | foo | | foo_doc | | items | | mydoc | | products | | test_users | | users | | yyy | +---------------------------+ 20 rows in set (0.01 sec) mysql-sql> mysql-sql> \js Switching to JavaScript mode... mysql-js> session <NodeSession:root@localhost:8000> mysql-js> db = session.getSchema("x_protocol_test") <Schema:x_protocol_test> mysql-js> db.yyy.find().limit(1) [ { "_id": "4661c8c3e971b3fc4dcf4af757297cb5", "author": "Theodor Fontane", "currentlyReadingPage": 42, "isbn": "12345", "title": "xxxxx" } ] 1 document in set (0.01 sec) mysql-js> mysql-js> tbl = db.getTable("foo") <Table:foo> mysql-js> db.find().limit(1); Invalid object member find (AttributeError) mysql-js> db.select().limit(1); Invalid object member select (AttributeError) mysql-js> tbl.select().limit(1); +-----+-----+ | id | v | +-----+-----+ | 123 | xyz | +-----+-----+ 1 row in set (0.00 sec) mysql-js>
UART
UARTについて
http://www.altima.jp/column/fpga_edison/uart.html
UART / USART
https://www.youtube.com/watch?v=FQpbIvhY7es
UART = Universal Asyncronus Receiver-Transmitter
USART = Universal Syncronus / Asyncronus Receiver-Transmitter
RS-232
https://www.youtube.com/watch?v=XVEnxipCIJ0
RS-232 Recommended Standard
Tx <--> Rx
Tx = Transmmit Data Rx = Receive Data
DTR <--> DSR
DTR = Data Terminal Ready DSR = Data Set Ready
RST <--> CTS
RTS = Request To Send CTS = Carrier To Send
DCD = Data Carrier Detect RI = ??