IT練習ノート

IT関連で調べたこと(実際は嵌ったこと)を書いています。

関数のコンテキストの型はユニークに解決される

言われてみれば当たり前なのですが、これに嵌りました。

Num型を複数とる関数があって、Int型やDouble型などいろいろパラメータに与えたかったのですが、コンパイルエラーがとれませんでした。問題点をシンプルな例で示すと以下のようになります。

Num型を複数とる関数を定義します。数値のリストを2つとり、それぞれの要素を掛け合わせて、合計を取ります。

*Main> let sumtimes' = \xs ys -> sum $ zipWith (*) xs ys
*Main> :t sumtimes'
sumtimes' :: Num a => [a] -> [a] -> a

普通に動きます。

*Main> sumtimes' [1,2,3] [1,2,3]

<interactive>:4:1: warning: [-Wtype-defaults]
    • Defaulting the following constraints to type ‘Integer’
        (Num a0) arising from a use of ‘it’ at <interactive>:4:1-25
        (Show a0) arising from a use of ‘print’ at <interactive>:4:1-25
    • In the first argument of ‘print’, namely ‘it’
      In a stmt of an interactive GHCi command: print it
14
*Main> sumtimes' [1.0,2.0,3.0] [1.0,2.0,3.0]

<interactive>:5:1: warning: [-Wtype-defaults]
    • Defaulting the following constraints to type ‘Double’
        (Fractional a0) arising from a use of ‘it’ at <interactive>:5:1-37
        (Show a0) arising from a use of ‘print’ at <interactive>:5:1-37
    • In the first argument of ‘print’, namely ‘it’
      In a stmt of an interactive GHCi command: print it
14.0

型が曖昧で、ワーニングが出ていますが、型を明示的に指定すれば、ワーニングはなくなります。

*Main> sumtimes' [1::Int,2,3] [1,2,3]
14
*Main> sumtimes' [1,2,3] [1,2::Double,3]
14.0

ここまでは良いのですが、2つのバラメータに別の数値型のリストを与えた時は、コンパイルエラーになります。ここに気づかず時間を取られていまいました。

*Main> sumtimes' [1::Int,2,3] [1::Double,2,3]

<interactive>:8:25: error:
    • Couldn't match expected type ‘Int’ with actual type ‘Double’
    • In the expression: 1 :: Double
      In the second argument of ‘sumtimes'’, namely ‘[1 :: Double, 2, 3]’
      In the expression: sumtimes' [1 :: Int, 2, 3] [1 :: Double, 2, 3]
*Main>

IntIntegerでもコンパイルエラーになります。

*Main> sumtimes' [1::Int,2,3] [1::Integer,2,3]

<interactive>:12:25: error:
    • Couldn't match expected type ‘Int’ with actual type ‘Integer’
    • In the expression: 1 :: Integer
      In the second argument of ‘sumtimes'’, namely
        ‘[1 :: Integer, 2, 3]’
      In the expression: sumtimes' [1 :: Int, 2, 3] [1 :: Integer, 2, 3]
*Main>

Num a => [a] -> [a] -> aの2つのパラメータは同じaとなっているので、同じ型でなければなりません。Nun型のインスタンスならなんでもいいわけではありません。

git statusで追加したファイルが表示されない

新規に作成したファイルがgit statusで表示されず、少し焦りました。.gitignoreの指定対象になっていたようです。無理やりgit add``をしたところ、メッセージに教えてもらいました。.gitignore```の設定を修正しました。

$ git add src/DataBase/MySQLX/ExprParser.hs
The following paths are ignored by one of your .gitignore files:
src/DataBase/MySQLX/ExprParser.hs
Use -f if you really want to add them.

MySQLのサンプルデータベースのテーブル定義

いつも忘れるのでメモ

mysql-sql> use world_x;
Query OK, 0 rows affected (0.01 sec)
mysql-sql> show tables;
+-------------------+
| Tables_in_world_x |
+-------------------+
| city              |
| country           |
| countryinfo       |
| countrylanguage   |
+-------------------+
4 rows in set (0.01 sec)
mysql-sql> desc city;
+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| ID          | int(11)  | NO   | PRI | null    | auto_increment |
| Name        | char(35) | NO   |     |         |                |
| CountryCode | char(3)  | NO   |     |         |                |
| District    | char(20) | NO   |     |         |                |
| Info        | json     | YES  |     | null    |                |
+-------------+----------+------+-----+---------+----------------+
5 rows in set (0.09 sec)
mysql-sql> desc country;
+---------+----------+------+-----+---------+-------+
| Field   | Type     | Null | Key | Default | Extra |
+---------+----------+------+-----+---------+-------+
| Code    | char(3)  | NO   | PRI |         |       |
| Name    | char(52) | NO   |     |         |       |
| Capital | int(11)  | YES  |     | null    |       |
| Code2   | char(2)  | NO   |     |         |       |
+---------+----------+------+-----+---------+-------+
4 rows in set (0.01 sec)
mysql-sql> desc countryinfo;
+-------+-------------+------+-----+---------+------------------+
| Field | Type        | Null | Key | Default | Extra            |
+-------+-------------+------+-----+---------+------------------+
| doc   | json        | YES  |     | null    |                  |
| _id   | varchar(32) | NO   | PRI | null    | STORED GENERATED |
+-------+-------------+------+-----+---------+------------------+
2 rows in set (0.01 sec)
mysql-sql> desc countrylanguage;
+-------------+---------------+------+-----+---------+-------+
| Field       | Type          | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+-------+
| CountryCode | char(3)       | NO   | PRI |         |       |
| Language    | char(30)      | NO   | PRI |         |       |
| IsOfficial  | enum('T','F') | NO   |     | F       |       |
| Percentage  | float(4,1)    | NO   |     | 0.0     |       |
+-------------+---------------+------+-----+---------+-------+
4 rows in set (0.01 sec)
mysql-sql>

Haskellのソースコードの言語拡張をいい感じにフォーマットする

Haskellのコードの先頭に書くやつで、左側の({-#)は揃ってるけど右側(#-})を揃える

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE RecordWildCards #-}

vimtabularいれて、下記コマンド

:'<,'>Tabularize /#-}

Haskellでコンパイル時の特定のワーニングを抑制する

4.8. Warnings and sanity-checking

To turn off any warning, simply give the corresponding -fno-warn-... option on the command line.

replでは、

> :set -fno-warn-unused-do-bind

でいけます。

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の作り方

CPUの創りかた

CPUの創りかた

  • 読者が具体的なイメージを持って理解出来るように、文章が工夫されている。

  • 準備は必要最低限に絞っている。

    • ともかくその時点の知識で、まずは1bit CPUを作ってみる。
  • 前半の方は、必要最小限のアナログの説明もされている。

  • 6章からがCPUの説明

  • プルアップ(プルダウン)->CRフィルタ->チャタリング防止->シュミットトリガ->リセット回路の説明の流れが秀逸

    • ただし、シュミットトリガの説明は天下り
  • ROMを自作するので、ROMの基本的な構造が具体的にわかる。

    • ROMプログラムを格納する場所という(完全に間違いではないが)杓子定規に解釈すると誤解を招く表現の正しい解釈の説明がある。
  • P.132-P.134の配線パターンの部分はよくわからなかった。実際に自作するときは苦労しそう。

  • 前提知識

  • 数値の大小関係の判断 -> キャリーの有無で判断

  • ドライブ能力の説明あり

  • 引用

    • 転送の途中に演算回路があれば演算命令に化けるだけ (p.171)