IT練習ノート

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

ラムダ計算のビデオ講義

www.youtube.com

ラムダ計算とはなにか、なんで有用なのか、その由来 YコンビネータとDNAの相似

www.youtube.com

再帰 Yコンビネータ

www.youtube.com

歴史を手短に解説 ものまね鳥の話

PutをBitPutにするとflushされてしまう

Binary処理が定義されているとします。

例えば、下記は1Byteの処理です。

 > :t example_ColFlags
example_ColFlags :: ColFlags
 > :t put example_ColFlags
put example_ColFlags :: Put
 >
 > BSL.writeFile "work\\colflags.bin" (runPut $ put example_ColFlags)
 >
  Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F    
00000000: FF                                                 .

このようなPutが定義されているときに、前後にbit単位の処理を追加することを考えます。

joinPutを使うと、直掩までのBit処理がflushされてしまいます。

 > let foo = putBool True >> (joinPut $ put (example_ColFlags ::ColFlags)) >> putBool True
 > BSL.writeFile "work\\colflags.bin" (runPut $ runBitPut foo)
 >

ここでは、1bitを出しているので、ゼロフィルされて80が出力されてしまいます。この挙動はドキュメントに記載されています。

Run a Put inside BitPut. Any partially written bytes will be flushed before Put executes to ensure byte alignment.

  Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F    
00000000: 80 FF 80                                           ...

flushを避けるため、仕方がないので、バイト単位の処理はいったんByteStringにして、それをBit処理しました。

 > let foo = putBool True >> (Bit.putByteString $ BSL.toStrict $ runPut $ put (example_ColFlags ::ColFlags)) >> putBool True
 > BSL.writeFile "work\\colflags.bin" (runPut $ runBitPut foo)
  Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F    
00000000: FF C0                                              .@

いつも忘れるのでHaskellのテストの最小のひな型をメモ

package.yaml

tastyだけでなくtastyから利用するテストパッケージもdependenciesに追加する。(これを忘れていつも嵌る)

tests:
  testproj-test:
    main:                Test.hs
    source-dirs:         test
    ghc-options:
    - -threaded
    - -rtsopts
    - -with-rtsopts=-N
    dependencies:
    - testproj
    - tasty
    - tasty-discover
    - tasty-hunit
    - tasty-hspec
    - tasty-quickcheck
    - tasty-smallcheck
    - bytestring 

Hspecのひな型

テストされる側のファイルとテストファイルは同じ名前にはできない。 sは小文字

module Foo.Bar.TestBuzz

where

-- test
import Test.Tasty
import Test.Tasty.Hspec

-- my library
import Foo.Bar.Buzz

getContext = return "dummy"

spec_template = do
    before getContext $ do
      describe "some descriptions" $ do
        it "descripe it" $ \_-> True `shouldBe` True

ghciをテスト側で呼び出す

stack ghci :testproj-test

実行方法

*> hspec spec_template

some descriptions
  descripe it FAILED [1]

Failures:

  test\Foo\Bar\TestBuzz.hs:17:
  1) some descriptions descripe it
       expected: True
        but got: False

Randomized with seed 285726028

Finished in 0.0081 seconds
1 example, 1 failure
*** Exception: ExitFailure 1

Haskellタプルは実質15個まで

タプルでshoweqが定義されているのは15個まで

タプル15個

 > type Foo = (Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool)
  > (True, False, True, True, True, True, True, True, True, True, True, True, True, True, True) :: Foo
(True,False,True,True,True,True,True,True,True,True,True,True,True,True,True)

タプル16個

> type Foo = (Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool, Bool)
 > (True, False, True, True, True, True, True, True, True, True, True, True, True, True, True, True) :: Foo

<interactive>:65:1: error:
    ? No instance for (Show Foo) arising from a use of ‘print’
    ? In a stmt of an interactive GHCi command: print it
 >

HaskellのBitの取り扱い

処理の流れ

Binary.BitsからBinaryに直してBinary側でrunする。

パッケージで言えば

Data.Binary.Bits.Put -> Data.Binary.Put -> Data.ByteString.Lazy

Data.Binary.Bits.Get -> Data.Binary.Get -> Data.ByteString.Lazy

動作例

> BL.writeFile "work\\bit01.bin" $ runPut $ runBitPut $ putBool True
  Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F    
00000000: 80   
> let tttt = putBool True >> putBool True >> putBool True >> putBool True
> BL.writeFile "work\\bit01.bin" $ runPut $ runBitPut tttt
>
  Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F    
00000000: F0                                                 p

QuickCheckで固定長文字列を作る

*> sample' (vectorOf 4 $ choose ('a','z'))
["jvnv","ylqf","aoud","bdha","lekn","ahoy","yzdp","nyso","zzlo","gjii","cyjg"]

Ascii文字列とかUnicode文字列とか生成する機能があります。一度しっかりドキュメントを読んでおくとお釣りか来る感じ。

*> sample' (arbitrary :: Gen ASCIIString)
[ASCIIString {getASCIIString = ""},ASCIIString {getASCIIString = "$"},ASCIIString {getASCIIString = "j6&,"},ASCIIString {getASCIIString = "oK\r"},ASCIIString {getASCIIString = "<C\RSed"},ASCIIString {getASCIIString = "\ETX"},ASCIIString {getASCIIString = "UW%\\0,\EM"},ASCIIString {getASCIIString = "\GS\n\ETB229\\|6"},ASCIIString {getASCIIString = "]4"},ASCIIString {getASCIIString = "hS~\ETB0,6=#=AR\SUBk|\b\a-"},ASCIIString {getASCIIString = "Wc\f\r\aj`\t%"}]
*> sample' (arbitrary :: Gen UnicodeString)
[UnicodeString {getUnicodeString = ""},UnicodeString {getUnicodeString = "\1034127\1073198"},UnicodeString {getUnicodeString = "\81677\1040544\831699"},UnicodeString {getUnicodeString = "\1113493\21462"},UnicodeString {getUnicodeString = "\334309\608748\266552\817694\1089443\918361"},UnicodeString {getUnicodeString = "\1057239\620355\610231\833658\1060579\1092217\532093\541595\1046677"},UnicodeString {getUnicodeString = "\996908\202855\651934\1027497"},UnicodeString {getUnicodeString = "\2950\849693\955293\894527\161271\801140\977486\785568\832124\322455\534586"},UnicodeString {getUnicodeString = ""},UnicodeString {getUnicodeString = "\97513\904222\107840\484931\1105\738793\459023\934071"},UnicodeString {getUnicodeString = "\744355\735021\421255\647867\959520\264100\912824\769664\548809\993941\585201\662346\949657"}]

Windows10へのGitのインストール

インストールのログ

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Users\User> iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
PowerShell requires an execution policy of 'RemoteSigned' to run Scoop.
To make this change please run:
'Set-ExecutionPolicy RemoteSigned -scope CurrentUser'
PS C:\Users\User> Set-ExecutionPolicy RemoteSigned -scope CurrentUser

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y
PS C:\Users\User> iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
Initializing...
Downloading...
Extracting...
Creating shim...
Adding ~\scoop\shims to your path.
Scoop was installed successfully!
Type 'scoop help' for instructions.
PS C:\Users\User> scoop install git
Installing '7zip' (18.05) [64bit]
7z1805-x64.msi (1.7 MB) [=====================================================================================] 100%
Checking hash of 7z1805-x64.msi... ok.
Extracting... done.
Linking ~\scoop\apps\7zip\current => ~\scoop\apps\7zip\18.05
Creating shim for '7z'.
Creating shortcut for 7-Zip (7zFM.exe)
'7zip' (18.05) was installed successfully!
Installing 'git' (2.17.0.windows.1) [64bit]
PortableGit-2.17.0-64-bit.7z.exe (36.6 MB) [==================================================================] 100%
Checking hash of PortableGit-2.17.0-64-bit.7z.exe... ok.
Extracting... done.
Linking ~\scoop\apps\git\current => ~\scoop\apps\git\2.17.0.windows.1
Creating shim for 'git'.
Creating shim for 'gitk'.
Creating shim for 'git-gui'.
Creating shim for 'tig'.
Creating shim for 'git-bash'.
Creating shortcut for Git Bash (git-bash.exe)
Running post-install script...
'git' (2.17.0.windows.1) was installed successfully!
Notes
-----
To get Git to recognise OpenSSH, you will need to run

scoop install openssh
[environment]::setenvironmentvariable('GIT_SSH', (resolve-path (scoop which ssh)), 'USER')

and then restart powershell.
PS C:\Users\User> scoop install openssh
Updating Scoop...
Scoop was updated successfully!
Installing 'openssh' (5.4p1-1) [64bit]
openssh-5.4p1-1-msys-1.0.13-bin.tar.lzma (274.7 KB) [=====================================================================================================================] 100%
openssh-5.4p1-1-msys-1.0.13-lic.tar.lzma (4.8 KB) [=======================================================================================================================] 100%
msysCORE-1.0.13-2-msys-1.0.13-bin.tar.lzma (610.1 KB) [===================================================================================================================] 100%
zlib-1.2.3-2-msys-1.0.13-dll.tar.lzma (36.7 KB) [=========================================================================================================================] 100%
libminires-1.02_1-2-msys-1.0.13-dll.tar.lzma (11.4 KB) [==================================================================================================================] 100%
libopenssl-1.0.0-1-msys-1.0.13-dll-100.tar.lzma (654.9 KB) [==============================================================================================================] 100%
Checking hash of openssh-5.4p1-1-msys-1.0.13-bin.tar.lzma... ok.
Extracting... done.
Checking hash of openssh-5.4p1-1-msys-1.0.13-lic.tar.lzma... ok.
Extracting... done.
Checking hash of msysCORE-1.0.13-2-msys-1.0.13-bin.tar.lzma... ok.
Extracting... done.
Checking hash of zlib-1.2.3-2-msys-1.0.13-dll.tar.lzma... ok.
Extracting... done.
Checking hash of libminires-1.02_1-2-msys-1.0.13-dll.tar.lzma... ok.
Extracting... done.
Checking hash of libopenssl-1.0.0-1-msys-1.0.13-dll-100.tar.lzma... ok.
Extracting... done.
Linking ~\scoop\apps\openssh\current => ~\scoop\apps\openssh\5.4p1-1
Creating shim for 'scp'.
Creating shim for 'sftp'.
Creating shim for 'slogin'.
Creating shim for 'ssh-add'.
Creating shim for 'ssh-agent'.
Creating shim for 'ssh-keygen'.
Creating shim for 'ssh-keyscan'.
Creating shim for 'ssh'.
'openssh' (5.4p1-1) was installed successfully!
PS C:\Users\User> scoop install git
WARN  'git' (2.17.0.windows.1) is already installed.
Use 'scoop update git' to install a new version.
PS C:\Users\User> [environment]::setenvironmentvariable('GIT_SSH', (resolve-path (scoop which ssh)), 'USER')
PS C:\Users\User>